diff options
| author | 2026-02-22 20:15:50 +0300 | |
|---|---|---|
| committer | 2026-02-22 20:15:50 +0300 | |
| commit | db8bb97dfa2dacef002a1f349ea970d76fee4fc9 (patch) | |
| tree | 7de11be3a01a6ef83a218dc98d90586dd1afb09a /README.md | |
| parent | Добавил утилитарные функции для моделей (diff) | |
| download | conf-db8bb97dfa2dacef002a1f349ea970d76fee4fc9.tar.gz conf-db8bb97dfa2dacef002a1f349ea970d76fee4fc9.tar.bz2 conf-db8bb97dfa2dacef002a1f349ea970d76fee4fc9.tar.xz conf-db8bb97dfa2dacef002a1f349ea970d76fee4fc9.zip | |
Refactoringv0.0.4
Diffstat (limited to '')
| -rw-r--r-- | README.md | 211 |
1 files changed, 150 insertions, 61 deletions
@@ -1,6 +1,6 @@ # conf -Go библиотека для чтения конфигурационных файлов в формате `.conf`. +Go библиотека для парсинга конфигурационных файлов `.conf`. ## Установка @@ -10,17 +10,15 @@ go get go.neonxp.ru/conf ## Особенности формата -- Простые присваивания: `key = value;` -- Строковые значения: `"text"` или `'text'` -- Многострочные строки: ``` `text` ``` -- Числовые значения: целые и дробные, включая отрицательные -- Булевы значения: `true` / `false` -- Директивы/команды: `directive arg1 arg2;` -- Групповые директивы с блоками кода: `directive { ... }` -- Комментарии от `#` до конца строки -- Поддержка кириллицы и UTF-8 +- **Присваивания**: `key = value;` +- **Типы значений**: строки (двойные/одинарные кавычки, backticks), числа (целые/дробные), булевы значения +- **Директивы**: `directive arg1 arg2;` +- **Блочные директивы**: `directive { ... }` +- **Комментарии**: `#` до конца строки +- **UTF-8**: включая кириллицу +- **Подстановка переменных окружения**: `$VAR` -## Пример использования +## Быстрый старт ```go package main @@ -28,86 +26,163 @@ package main import ( "fmt" "go.neonxp.ru/conf" + "go.neonxp.ru/conf/model" + "go.neonxp.ru/conf/visitor" ) func main() { - doc, err := conf.LoadFile("./config.conf") - if err != nil { + cfg := conf.New() + if err := cfg.LoadFile("config.conf"); err != nil { panic(err) } - // Получение значения по ключу - values := doc.Get("my_key") - fmt.Println(values) - - // Получение команд по имени - commands := doc.Commands("directivename") - fmt.Println(commands) + v := visitor.NewDefault() + if err := cfg.Process(v); err != nil { + panic(err) + } - // Все переменные - vars := doc.Vars() + // Доступ по пути с точечной нотацией + val, err := v.Get("server.host") + if err != nil { + panic(err) + } + fmt.Println(val.String()) // localhost - // Все элементы документа - items := doc.Items() + port, err := v.Get("server.port") + fmt.Println(port.Int()) // 8080 } ``` ## Пример конфигурационного файла ```conf -# Пример конфигурации +# Переменная окружения: db_file = $HOME "/app/data.db"; + +# Простые присваивания +rss = "https://neonxp.ru/feed/"; +host = "localhost"; +port = 8080; +debug = true; + +# Директивы с аргументами +telegram "bot123" "-1003888840756" { + token = "token_value"; + admin_chat = "@admin"; +} + +# Вложенные блоки +server { + host = "localhost"; + port = 8080; -# Простое присваивание -simple_key = value; + ssl { + enabled = true; + cert = "/etc/ssl/cert.pem"; + } -# Многострочное присваивание -string_key = - "value" - 'string'; + middleware "auth" { + enabled = true; + secret = "$JWT_SECRET"; + } +} -# Многострочные строки (backticks) -multiline_string = ` - multiline - string - 123 +# Многострочные строки +template = ` + <!DOCTYPE html> + <html> + <body>Hello</body> + </html> `; +``` + +## API -# Числа и булевы значения -int_key = -123.456; -bool_key = true; +### Загрузка конфигурации -# Директивы -expression1 argument1 "argument2" 123; +```go +cfg := conf.New() -# Групповая директива -group_directive_without_arguments { - expression1 argument2 "string" 123 true; - expression2 argument3 "string111" 123321 false; +// Из файла +cfg.LoadFile("config.conf") - children_group "some argument" { - # Вложенная группа - } +// Из памяти +cfg.Load("inline", []byte("key = value;")) +``` + +### Обработка через Visitor + +Библиотека использует паттерн Visitor для обхода конфигурации: + +```go +type Visitor interface { + VisitDirective(ident string, args Values, body Body) error + VisitSetting(key string, values Values) error } +``` -# Групповая директива с аргументами -group_directive_with_argument "argument1" 'argument2' { - child_val = "children value"; +### Get-методы на Values + +| Метод | Описание | +|-------|----------| +| `String()` | Строковое представление через пробел | +| `Int()` | Преобразование в int (одно значение) | +| `BuildString(lookups...)` | Сборка строки с подстановками | + +### Подстановка переменных окружения + +```go +vals, _ := v.Get("db_file") +path := vals.BuildString(model.LookupEnv) +// $HOME → "/home/user", результат: "/home/user/app/data.db" +``` + +### Кастомные подстановки + +```go +substitutions := map[model.Word]string{ + "APP_DIR": "/opt/myapp", + "LOG_LEVEL": "debug", } + +path := vals.BuildString(model.LookupSubst(substitutions), model.Origin) ``` -## API +## Реализация собственного Visitor -### Функции +```go +type MyVisitor struct{} -- `LoadFile(filename string) (*model.Doc, error)` - загрузка конфигурации из файла -- `Load(name string, input []byte) (*model.Doc, error)` - парсинг конфигурации из байтов +func (m *MyVisitor) VisitDirective(ident string, args model.Values, body model.Body) error { + fmt.Printf("Directive: %s, args: %s\n", ident, args.String()) + return body.Execute(m) // Рекурсивный обход тела +} -### Методы `*model.Doc` +func (m *MyVisitor) VisitSetting(key string, values model.Values) error { + fmt.Printf("Setting: %s = %s\n", key, values.String()) + return nil +} +``` + +## Грамматика (EBNF) -- `Get(key string) Values` - получить значения по ключу -- `Commands(name string) Commands` - получить команды по имени -- `Vars() map[string]Values` - получить все переменные -- `Items() []any` - получить все элементы документа +``` +Config = Doc . +Doc = Stmt { Stmt } . +Stmt = Word ( Assignment | Command ) . + +Assignment = "=" Values br . +Command = [Values] ( Body | br ) . + +Values = Value { Value } . +Value = Word | String | Number | Boolean . +Body = "{" [ Doc ] "}" . + +Word = word (alpha | "$" | "_") {alpha | number | "$" | "_"} . +String = `"[^"]*"` | `'[^']*'` | '`' { `[^`]' } '`' . +Number = `-?[0-9]+(\.[0-9]+)?` . +Boolean = `true` | `false` . +br = ";" . +``` ## Требования @@ -115,4 +190,18 @@ group_directive_with_argument "argument1" 'argument2' { ## Лицензия -См. файл [LICENSE](LICENSE) +Этот проект лицензирован в соответствии с GNU General Public License версии 3 +(GPLv3). Подробности смотрите в файле [LICENSE](LICENSE). + +``` + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2026 Alexander NeonXP Kiryukhin <i@neonxp.ru> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. +``` + +## Автор + +- Александр Кирюхин <i@neonxp.ru> |
