Skip to content

Commit 84c3ea1

Browse files
authored
feat: add corn file format (#694)
This adds `corn` as a new file format. I've enabled it by default as per the current standards, but did see discussion in #621 as to possibly changing this approach. https://cornlang.dev
2 parents c625059 + 0aca5de commit 84c3ea1

File tree

6 files changed

+399
-0
lines changed

6 files changed

+399
-0
lines changed

Cargo.lock

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ json = ["serde_json"]
126126
yaml = ["yaml-rust2"]
127127
ini = ["rust-ini"]
128128
json5 = ["json5_rs", "dep:serde-untagged"]
129+
corn = ["dep:corn"]
129130
convert-case = ["convert_case"]
130131
preserve_order = ["indexmap", "toml?/preserve_order", "serde_json?/preserve_order", "ron?/indexmap"]
131132
async = ["async-trait"]
@@ -141,6 +142,7 @@ yaml-rust2 = { version = "0.10.4", optional = true }
141142
rust-ini = { version = "0.21.3", optional = true }
142143
ron = { version = "0.8.1", optional = true }
143144
json5_rs = { version = "0.4.1", optional = true, package = "json5" }
145+
corn = { version = "0.10.0", optional = true, package = "libcorn" }
144146
indexmap = { version = "2.11.4", features = ["serde"], optional = true }
145147
convert_case = { version = "0.6.0", optional = true }
146148
pathdiff = "0.2.3"

src/file/format/corn.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use crate::value::{Value, ValueKind};
2+
use crate::{format, Map};
3+
use std::error::Error;
4+
5+
pub(crate) fn parse(
6+
uri: Option<&String>,
7+
text: &str,
8+
) -> Result<Map<String, Value>, Box<dyn Error + Send + Sync>> {
9+
let value = from_corn_value(uri, &corn::parse(text)?);
10+
format::extract_root_table(uri, value)
11+
}
12+
13+
fn from_corn_value(uri: Option<&String>, value: &corn::Value<'_>) -> Value {
14+
match value {
15+
corn::Value::String(value) => Value::new(uri, ValueKind::String(value.to_string())),
16+
corn::Value::Integer(value) => Value::new(uri, ValueKind::I64(*value)),
17+
corn::Value::Float(value) => Value::new(uri, ValueKind::Float(*value)),
18+
corn::Value::Boolean(value) => Value::new(uri, ValueKind::Boolean(*value)),
19+
corn::Value::Object(value) => Value::new(
20+
uri,
21+
ValueKind::Table(
22+
value
23+
.iter()
24+
.map(|(key, value)| (key.to_string(), from_corn_value(uri, value)))
25+
.collect(),
26+
),
27+
),
28+
corn::Value::Array(value) => Value::new(
29+
uri,
30+
ValueKind::Array(
31+
value
32+
.iter()
33+
.map(|value| from_corn_value(uri, value))
34+
.collect(),
35+
),
36+
),
37+
corn::Value::Null(_) => Value::new(uri, ValueKind::Nil),
38+
}
39+
}

src/file/format/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ mod ron;
2121
#[cfg(feature = "json5")]
2222
mod json5;
2323

24+
#[cfg(feature = "corn")]
25+
mod corn;
26+
2427
/// File formats provided by the library.
2528
///
2629
/// Although it is possible to define custom formats using [`Format`] trait it is recommended to use `FileFormat` if possible.
@@ -50,6 +53,10 @@ pub enum FileFormat {
5053
/// JSON5 (parsed with json5)
5154
#[cfg(feature = "json5")]
5255
Json5,
56+
57+
/// Corn (parsed with `libcorn`)
58+
#[cfg(feature = "corn")]
59+
Corn,
5360
}
5461

5562
impl FileFormat {
@@ -67,6 +74,8 @@ impl FileFormat {
6774
FileFormat::Ron,
6875
#[cfg(feature = "json5")]
6976
FileFormat::Json5,
77+
#[cfg(feature = "corn")]
78+
FileFormat::Corn,
7079
]
7180
}
7281

@@ -90,6 +99,9 @@ impl FileFormat {
9099
#[cfg(feature = "json5")]
91100
FileFormat::Json5 => &["json5"],
92101

102+
#[cfg(feature = "corn")]
103+
FileFormat::Corn => &["corn"],
104+
93105
#[cfg(all(
94106
not(feature = "toml"),
95107
not(feature = "json"),
@@ -126,6 +138,9 @@ impl FileFormat {
126138
#[cfg(feature = "json5")]
127139
FileFormat::Json5 => json5::parse(uri, text),
128140

141+
#[cfg(feature = "corn")]
142+
FileFormat::Corn => corn::parse(uri, text),
143+
129144
#[cfg(all(
130145
not(feature = "toml"),
131146
not(feature = "json"),

0 commit comments

Comments
 (0)