Skip to content

Commit 401b52e

Browse files
committed
rustell::encode module wip
1 parent f72da47 commit 401b52e

File tree

4 files changed

+88
-5
lines changed

4 files changed

+88
-5
lines changed

rust/rustell/src/encode.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use super::*;
2+
use std::iter::{IntoIterator, once};
3+
use std::vec::IntoIter;
4+
5+
pub fn expr<'a>(
6+
ast: Vec<Expr<'a>>,
7+
) -> impl Iterator<Item = &'a str> {
8+
ast.into_iter().flat_map(expr_one)
9+
}
10+
11+
fn expr_one<'a>(ast: Expr<'a>) -> IntoIter<&'a str> {
12+
match ast {
13+
Expr::Use(x) => expr_use(true, x)
14+
.chain(vec![";"].into_iter())
15+
.collect::<Vec<&'a str>>()
16+
.into_iter(),
17+
Expr::Other(x) => vec![x].into_iter(),
18+
}
19+
}
20+
21+
fn expr_use<'a>(
22+
top: bool,
23+
ast: ExprUse<'a>,
24+
) -> IntoIter<&'a str> {
25+
let x0 = if top { vec!["use"] } else { vec![] };
26+
let x1 = match ast {
27+
ExprUse::Item {
28+
module,
29+
rename,
30+
nested,
31+
} => expr_use_item(module, rename, nested),
32+
ExprUse::Many(xs) => expr_use_many(xs),
33+
ExprUse::Glob => vec!["*"].into_iter(),
34+
};
35+
x0.into_iter()
36+
.chain(x1.into_iter())
37+
.collect::<Vec<_>>()
38+
.into_iter()
39+
}
40+
41+
fn expr_use_item<'a>(
42+
module: &'a str,
43+
rename: Option<&'a str>,
44+
nested: Option<Box<ExprUse<'a>>>,
45+
) -> IntoIter<&'a str> {
46+
let module_iter = once(module);
47+
48+
let rename_iter = rename
49+
.map(|x| once("as").chain(once(x)))
50+
.into_iter()
51+
.flatten();
52+
53+
let nested_iter = nested
54+
.map(|x| once("::").chain(expr_use(false, *x)))
55+
.into_iter()
56+
.flatten();
57+
58+
module_iter
59+
.chain(rename_iter)
60+
.chain(nested_iter)
61+
.collect::<Vec<_>>()
62+
.into_iter()
63+
}
64+
65+
fn expr_use_many<'a>(
66+
xs: Vec<ExprUse<'a>>,
67+
) -> IntoIter<&'a str> {
68+
xs.into_iter()
69+
.flat_map(|x| expr_use(false, x))
70+
.collect::<Vec<_>>()
71+
.into_iter()
72+
}

rust/rustell/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod decode;
2+
pub mod encode;
23
pub use chumsky::prelude::Parser;
34

45
#[derive(Eq, PartialEq, Debug, Clone)]

rust/rustell/src/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rustell::decode;
2+
use rustell::encode;
23
use rustell::*;
34
use std::io::{self, Read};
45

@@ -8,7 +9,9 @@ fn main() {
89
.read_to_string(&mut src)
910
.expect("Failed to read stdin");
1011
match decode::expr().parse(src.trim()).into_result() {
11-
Ok(ast) => println!("{:#?}", ast),
12+
Ok(ast) => {
13+
encode::expr(ast).for_each(|x| print!("{}", x))
14+
}
1215
Err(errs) => {
1316
errs.into_iter().for_each(|e| println!("{e:?}"))
1417
}

rust/rustell/tests/integration.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use rustell::decode;
2+
use rustell::encode;
23
use rustell::*;
34

45
#[test]
56
fn test_parser() {
6-
let lhs = "use std::io::Read;";
7-
let rhs = vec![Expr::Use(ExprUse::Item {
7+
let src = "use std::io::Read;";
8+
let slp = sloppy(src);
9+
let ast = vec![Expr::Use(ExprUse::Item {
810
module: "std",
911
rename: None,
1012
nested: Some(Box::new(ExprUse::Item {
@@ -17,8 +19,9 @@ fn test_parser() {
1719
})),
1820
})),
1921
})];
20-
assert_eq!(parse(lhs), rhs);
21-
assert_eq!(parse(&sloppy(lhs)), rhs)
22+
assert_eq!(parse(src), ast);
23+
assert_eq!(parse(&slp), ast);
24+
assert_eq!(parse(&encode(ast.clone())), ast)
2225
}
2326

2427
#[test]
@@ -321,3 +324,7 @@ fn sloppy(src: &str) -> String {
321324
fn parse(src: &str) -> Vec<Expr> {
322325
decode::expr().parse(src).into_result().unwrap()
323326
}
327+
328+
fn encode(ast: Vec<Expr>) -> String {
329+
encode::expr(ast).collect()
330+
}

0 commit comments

Comments
 (0)