5 个版本 (3 个重大更新)

0.3.0 2022 年 9 月 7 日
0.2.0 2022 年 1 月 29 日
0.1.0 2022 年 1 月 26 日
0.0.1 2022 年 1 月 25 日
0.0.0-alpha2022 年 1 月 24 日

#657配置

MIT 许可协议

42KB
532

🌽 玉米

简单易用的配置语言。

Corn 设计灵感来自 JSON 和 Nix,旨在创造一种易于编写、适合配置文件且功能集小的语言,您可以在几分钟内学会它。它源于以下挫败感

  • 尽管人们经常将其用作配置语言,但 JSON 本身并不是一种配置语言
  • TOML 适用于扁平结构,但随着对象深度的增加,会变得很丑陋
  • YAML 非常复杂,其空白规则使其容易出错

Corn 不是什么

Corn 不是一个完整的编程语言,也不会试图成为。它没有变量,没有插值,也没有语句块。

同样,Corn 不是一个数据交换格式。与 JSON 或 YAML 或 TOML 不同,您不能将代码反序列化为 Corn。

用法

作为二进制文件

Corn 可以作为可执行二进制文件安装,用于将 .corn 格式的文件转换为任何支持的输出格式。目前这些是

  • JSON
  • YAML
  • TOML

支持 Windows、Linux 和 macOS。

使用 cargo 安装它

cargo install cornfig

然后简单地

cornfig file.corn
cornfig file.corn -t yaml

作为库

Corn 可以作为 Rust 库使用,以直接反序列化配置文件,无需转换为其他文件格式。

crate | 文档

use cornfig::parse;

fn main() {
    let corn = "{foo = 42}";

    let config = parse(corn).unwrap();
    let json = serde_json::to_string_pretty(&config.value).unwrap();

    assert_eq!(json, "{\"foo\": 42}");
}

可用于 NodeJS 和浏览器的 WASM 版本也可用。

npm

import * as corn from 'cornfig-wasm';

const parsed = corn.parse('{foo = "bar"}');
console.log(parsed.value) // { foo: "bar" }

编写 Corn

本节以 JSON 格式提供所有输出。请记住,您可以将输出格式设置为任何支持的格式!

所有 Corn 文件都必须包含一个顶层对象,其中包含键/值。键不需要引号,并且可以包含任何 Unicode 字符,除了空白和等于 =(是的,甚至是表情符号)。

值必须是以下之一

  • 字符串
  • 整数
  • 浮点数
  • 布尔值
  • 对象
  • 数组
  • 空值
  • 输入

(以下将详细介绍这些类型)

因此,一个非常基础的例子将是

{
    hello = "world"
}

它当然映射到以下 JSON 格式

{
  "hello": "world"
}

一个更复杂的例子可能是这样的 package.json。这使用了输入、各种其他数据类型和键链。

let {
    $entry = "dist/index.js"
    $author = { name = "John Smith" email = "[email protected]" }
} in {
    name = "example-package"
    version = "1.0.0"
    main = $entry
    bin.executable = $entry
    private = false
    
    author = $author
    author.url = "https://example.com" 
    
    contributors = [ $author ]
    
    scripts.build = "tsc"
    scripts.run = "node dist"
    
    dependencies = {
        dotenv = "^8.2.0"
        // put the rest of your deps here...
    }
    
    devDependencies.typescript = "^4.5"
    
    config.port = 8080
    config.hostname = null
}
这个输出比其他输出要长一些,所以请点击此处展开并查看。
{
  "author": {
    "email": "[email protected]",
    "name": "John Smith",
    "url": "https://example.com"
  },
  "bin": {
    "filebrowser": "dist/index.js"
  },
  "config": {
    "hostname": null,
    "port": 8080
  },
  "contributors": [
    {
      "email": "[email protected]",
      "name": "John smith"
    }
  ],
  "dependencies": {
    "dotenv": "^8.2.0"
  },
  "devDependencies": {
    "typescript": "^4.5"
  },
  "main": "dist/index.js",
  "name": "example-package",
  "private": false,
  "scripts": {
    "build": "tsc",
    "run": "node dist"
  },
  "version": "1.0.0"
}

数据类型

字符串

字符串必须用双引号括起来。所有Unicode字符都受支持。

foo = "bar"

整数

整数是有符号的64位,这意味着你可以使用从 -92233720368547758089223372036854775807 之间的任何值。

answer = 42

浮点数

使用双精度(64位)浮点数。

pi = 3.14159

布尔值

正如你所期望的。

not_false = true

对象

对象使用大括号标记开始和结束。它们包含键/值对。

对象内嵌对象或数组没有限制。

{
  foo = "bar"
  hello = "world"
}

数组

数组使用方括号标记开始和结束。值由空格分隔。像对象一样,嵌套数组和对象也没有限制。

    array = [ 1 2 3 ]

你还可以随意包含空白,并混合元素类型。

{
    array = [ 1 2 3 ]
    array2 = [
        "one"
        2
        true
        { three = 3 }
    ]
}

上面的内容转换成以下JSON

{
  "array": [
    1,
    2,
    3
  ],
  "array2": [
    "one",
    2,
    true,
    {
      "three": 3
    }
  ]
}

空值

空值简单地使用 null 关键字。

foo = null

输入

有时在配置文件顶部存储一些值可能很有用,稍后使用或重复使用它们,甚至使用它们来组合更复杂的价值。Corn支持配置输入,类似于变量,但它们不会改变。

所有输入名称以美元符号 $ 开头,后跟一个ASCII字母字符或下划线 _。然后可以跟任意数量的ASCII字母数字字符或下划线。

输入可以用来存储任何值类型,或包含在字符串中。

要声明输入,必须在配置文件开始处包括一个 let { } in 块。

let { 
    $firstName = "John"
    $lastName = "Smith" 
    
    $birthday = {
        day = 1
        month = 1
        year = 1970
    }
    
} in {
    name = {
        first = $firstName
        last = $lastName
    }
    
    dob = $birthday
}

除了声明自己的输入外,你还可以通过在输入名称前加 $env_ 来访问任何环境变量。例如,要使用系统 PATH

{
    path = $env_PATH
}

将输出类似的内容

{
  "path": "/home/jake/.cargo/bin:/home/jake/.local/bin:/usr/local/bin:/usr/bin"
}

环境变量输入将回退到同名常规输入,允许你创建默认值。

输入的功能故意有限,如果你需要更多的功能,你应该使用完整的语言。话虽如此,它们可能提供了一种快速查看/更改值的方法,而不必在整个文件中搜索。

注释

在任何地方,你都可以使用 // 开始注释。注释以换行符 \n 结束。注释完全被忽略,不包括在输出中。

{
    // this is a single-line comment
    foo = bar // this is a mixed-line comment
}

嵌套键

在整个页面上,我们使用类似于这样的语法在对象中创建对象

{
    foo = {
        bar = "baz"
    }
}

虽然这对于简短的情况来说是可行的,但它很快就会变得繁琐,而且大括号在阅读时增加了很多噪音。

为了解决这个问题,可以通过键链创建深层次的对象。

{
    foo.bar = "baz"
}

这在JSON中是

{
  "foo": {
    "bar": "baz"
  }
}

你可以随时混合匹配链式键和嵌套对象。

{
    foo = {
        bar.baz = 42
        qux = true
    }
    
    foo.quux = [ "green eggs" "ham" ]
}

JSON

{
  "foo": {
    "bar": {
      "baz": 42
    },
    "qux": true,
    "quux": ["green eggs", "ham"]
  }
}

空白

Corn中的几乎所有空白都是可选的,因为关键字和类型在结束时就会结束。只有少数例外。

  • 整数或浮点数之后必须用空白与整数或浮点数分隔,以告知一个在哪里结束,另一个在哪里开始。
  • 对输入的引用必须以空白结束,否则解析器无法知道名称在哪里结束。
  • key=value 赋值之间必须有空白。

这意味着以下内容是完全有效的(尽管出于一致性和可读性的考虑,这强烈不推荐)

{
    one={foo="bar" bar="foo"}
    two={foo=1 bar=2}
    three={foo=1.0 bar=2.0}
    four={foo=true bar=false}
    five={foo=null bar=null}
    six={foo={} bar={}}
    seven={foo=[] bar=[]}

    eight=["foo""bar"]
    nine=[truefalse]
    ten=[nullnull]
    eleven=[[][]]
    twelve=[{}{}]
}

事实上,我们甚至可以将它简化为一行

{one={foo="bar" bar="foo"} two={foo=1 bar=2} three={foo=1.0 bar=2.0} four={foo=true bar=false} five={foo=null bar=null} six={foo={} bar={}} seven={foo=[] bar=[]} eight=["foo""bar"] nine=[truefalse] ten=[nullnull] eleven=[[][]] twelve=[{}{}]}

编辑器支持

VSCode

  • 基本语法高亮
  • 支持括号匹配和注释

插件 | 仓库

IntelliJ

  • 语法高亮
  • 解析、词法分析和实时错误检查
  • 支持括号匹配和注释
  • 基本完成支持
  • 基本重构支持
  • 基本格式化和代码样式选项

插件 | 仓库

贡献

我们非常欢迎贡献,但请在首先提交一个问题,因为并非所有潜在的功能都会被合并。

目前Corn处于非常早期的阶段。如果您想帮忙,我非常乐意看到以下内容

  • 更多输出格式
  • 现有功能的改进和修复
  • 更多测试
  • 更好的文档

运行测试

您必须设置 CORN_TEST=foobar,因为这需要环境变量测试。

WASM

WASM支持是一个名为wasm的功能,默认是禁用的。确保在构建时启用它

wasm-pack build -- --features wasm

依赖项

~6–17MB
~193K SLoC