Skip to content

Commit 64ae1e1

Browse files
authored
feat: metadata parser (#18)
1 parent 5804104 commit 64ae1e1

9 files changed

+455
-6
lines changed

src/error.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub enum NorgParseError {
99
Stage2(Vec<Simple<NorgToken>>),
1010
Stage3(Vec<Simple<NorgBlock>>),
1111
Stage4(Vec<Simple<NorgASTFlat>>),
12+
Meta(Simple<char>),
1213
}
1314

1415
impl From<Vec<Simple<char>>> for NorgParseError {
@@ -34,3 +35,9 @@ impl From<Vec<Simple<NorgASTFlat>>> for NorgParseError {
3435
NorgParseError::Stage4(error)
3536
}
3637
}
38+
39+
impl From<Simple<char>> for NorgParseError {
40+
fn from(error: Simple<char>) -> Self {
41+
NorgParseError::Meta(error)
42+
}
43+
}

src/lib.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub use crate::stage_3::*;
1010
pub use crate::stage_4::NorgAST;
1111

1212
mod error;
13+
pub mod metadata;
1314
mod stage_1;
1415
mod stage_2;
1516
mod stage_3;
@@ -101,11 +102,11 @@ mod tests {
101102
* Back to regular heading
102103
",
103104
]
104-
.into_iter()
105-
.map(|example| example.to_string() + "\n")
106-
.map(|str| parse_tree(&str))
107-
.try_collect()
108-
.unwrap();
105+
.into_iter()
106+
.map(|example| example.to_string() + "\n")
107+
.map(|str| parse_tree(&str))
108+
.try_collect()
109+
.unwrap();
109110
assert_yaml_snapshot!(headings_tree_examples);
110111
}
111112

src/metadata/mod.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
use chumsky::Parser;
2+
pub use stage_1::NorgMeta;
3+
4+
use crate::error::NorgParseError;
5+
6+
pub mod stage_1;
7+
8+
/// Parses the given input string to produce an AST for the metadata
9+
pub fn parse_metadata(input: &str) -> Result<NorgMeta, NorgParseError> {
10+
let processed = format!("{{\n{}\n}}\n", input.trim());
11+
Ok(stage_1::meta_parser().parse(processed)?)
12+
}
13+
14+
#[cfg(test)]
15+
mod tests {
16+
use insta::assert_yaml_snapshot;
17+
use itertools::Itertools;
18+
19+
use crate::metadata::parse_metadata;
20+
21+
#[test]
22+
fn common_metadata() {
23+
let examples: Vec<_> = [
24+
"
25+
title: Sunday November 17, 2024
26+
description: We Cooked
27+
authors: benlubas
28+
categories: journal
29+
created: 2024-11-18
30+
updated: 2024-11-18T17:58:21-0500
31+
version: 1.1.1
32+
",
33+
"
34+
title: Neorg Extras
35+
description: Extra lua code to configure Neorg
36+
authors: benlubas
37+
categories: [
38+
neorg
39+
nvim
40+
config
41+
]
42+
tangle: {
43+
languages: {
44+
lua: ~/github/.dotfiles/nvim/lua/benlubas/neorg/extras.lua
45+
}
46+
delimiter: heading
47+
}
48+
created: 2024-05-03T13:36:42-0500
49+
updated: 2024-10-27T11:12:32-0500
50+
version: 1.1.1
51+
",
52+
]
53+
.into_iter()
54+
.map(|example| example.to_string() + "\n")
55+
.map(|str| parse_metadata(&str))
56+
.try_collect()
57+
.unwrap();
58+
59+
assert_yaml_snapshot!(examples);
60+
}
61+
62+
#[test]
63+
fn arrays() {
64+
let examples: Vec<_> = [
65+
"empty_arr: []
66+
arr: [
67+
68+
]",
69+
"
70+
categories: [
71+
one
72+
two
73+
45
74+
]",
75+
"
76+
arr: [
77+
arrays can contain everything
78+
5
79+
-5
80+
6.02e27
81+
nil
82+
{
83+
x: y
84+
a: [
85+
b
86+
]
87+
}
88+
[]
89+
[
90+
hi
91+
hi
92+
]
93+
]",
94+
"arr:[]\na2:[\n]x: y",
95+
]
96+
.into_iter()
97+
.map(|example| example.to_string() + "\n")
98+
.map(|str| parse_metadata(&str))
99+
.try_collect()
100+
.unwrap();
101+
102+
assert_yaml_snapshot!(examples);
103+
}
104+
105+
#[test]
106+
fn keys_and_values() {
107+
let examples: Vec<_> = [
108+
"key: value",
109+
"x:y",
110+
"x :y",
111+
"x:5",
112+
"x:-4",
113+
"str:-4b",
114+
"nil:nil",
115+
"nil:",
116+
"still_nil:
117+
x: y",
118+
"
119+
key: value with : in it
120+
key_2: value with: in it
121+
",
122+
"keys: {
123+
in:
124+
objects: []
125+
}"
126+
]
127+
.into_iter()
128+
.map(|example| example.to_string() + "\n")
129+
.map(|str| parse_metadata(&str))
130+
.try_collect()
131+
.unwrap();
132+
133+
assert_yaml_snapshot!(examples);
134+
}
135+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
source: src/metadata/mod.rs
3+
expression: examples
4+
---
5+
- Object:
6+
arr:
7+
Array: []
8+
empty_arr:
9+
Array: []
10+
- Object:
11+
categories:
12+
Array:
13+
- Str: one
14+
- Str: two
15+
- Num: 45
16+
- Object:
17+
arr:
18+
Array:
19+
- Str: arrays can contain everything
20+
- Num: 5
21+
- Num: -5
22+
- Num: 6020000000000000000000000000
23+
- Nil
24+
- Object:
25+
a:
26+
Array:
27+
- Str: b
28+
x:
29+
Str: y
30+
- Array: []
31+
- Array:
32+
- Str: hi
33+
- Str: hi
34+
- Object:
35+
a2:
36+
Array: []
37+
arr:
38+
Array: []
39+
x:
40+
Str: y
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
source: src/metadata/mod.rs
3+
expression: examples
4+
---
5+
- Object:
6+
authors:
7+
Str: benlubas
8+
categories:
9+
Str: journal
10+
created:
11+
Str: 2024-11-18
12+
description:
13+
Str: We Cooked
14+
title:
15+
Str: "Sunday November 17, 2024"
16+
updated:
17+
Str: "2024-11-18T17:58:21-0500"
18+
version:
19+
Str: 1.1.1
20+
- Object:
21+
authors:
22+
Str: benlubas
23+
categories:
24+
Array:
25+
- Str: neorg
26+
- Str: nvim
27+
- Str: config
28+
created:
29+
Str: "2024-05-03T13:36:42-0500"
30+
description:
31+
Str: Extra lua code to configure Neorg
32+
tangle:
33+
Object:
34+
delimiter:
35+
Str: heading
36+
languages:
37+
Object:
38+
lua:
39+
Str: ~/github/.dotfiles/nvim/lua/benlubas/neorg/extras.lua
40+
title:
41+
Str: Neorg Extras
42+
updated:
43+
Str: "2024-10-27T11:12:32-0500"
44+
version:
45+
Str: 1.1.1
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
source: src/metadata/mod.rs
3+
expression: examples
4+
---
5+
- Object:
6+
key:
7+
Str: value
8+
- Object:
9+
x:
10+
Str: y
11+
- Object:
12+
x:
13+
Num: 5
14+
- Object:
15+
x:
16+
Num: -4
17+
- Object:
18+
str:
19+
Str: "-4b"
20+
- Object:
21+
nil: Nil
22+
- Object:
23+
nil: Nil
24+
- Object:
25+
still_nil: Nil
26+
x:
27+
Str: y
28+
- Object:
29+
key:
30+
Str: "value with : in it"
31+
key_2:
32+
Str: "value with: in it"
33+
- Object:
34+
keys:
35+
Object:
36+
in: Nil
37+
objects:
38+
Array: []
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
source: src/metadata/mod.rs
3+
expression: examples
4+
---
5+
- Object:
6+
key:
7+
Str: value
8+
- Object:
9+
x:
10+
Str: y
11+
- Object:
12+
x:
13+
Str: y
14+
- Object:
15+
x:
16+
Num: 5
17+
- Object:
18+
x:
19+
Num: -4
20+
- Object:
21+
str:
22+
Str: "-4b"
23+
- Object:
24+
nil: Nil
25+
- Object:
26+
nil: Nil
27+
- Object:
28+
still_nil: Nil
29+
x:
30+
Str: y
31+
- Object:
32+
key:
33+
Str: "value with : in it"
34+
key_2:
35+
Str: "value with: in it"
36+
- Object:
37+
keys:
38+
Object:
39+
in: Nil
40+
objects:
41+
Array: []

0 commit comments

Comments
 (0)