Skip to content

Commit

Permalink
fix(parser): panic when input references another input
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeStanger committed Nov 27, 2022
1 parent 7a2f7b5 commit 7ea024d
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 23 deletions.
6 changes: 6 additions & 0 deletions assets/inputs/input_references_input.corn
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
let {
$foo = "bar"
$baz = $foo
} in {
foo = $baz
}
3 changes: 3 additions & 0 deletions assets/outputs/json/input_references_input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"foo": "bar"
}
2 changes: 2 additions & 0 deletions assets/outputs/toml/input_references_input.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo = 'bar'

2 changes: 2 additions & 0 deletions assets/outputs/yaml/input_references_input.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo: bar

28 changes: 15 additions & 13 deletions libcorn/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,24 @@ impl std::fmt::Display for Rule {
}

struct CornParser<'a> {
input_block: Option<Pair<'a, Rule>>,
inputs: Inputs<'a>,
}

impl<'a> CornParser<'a> {
pub fn new(input_block: Option<Pair<'a, Rule>>) -> Self {
let inputs = input_block
.map(|block| Self::parse_assign_block(block).unwrap())
.unwrap_or_else(HashMap::new);

Self { inputs }
let inputs = HashMap::new();
Self {
input_block,
inputs,
}
}

pub fn parse(self, object_block: Pair<'a, Rule>) -> Result<Value> {
pub fn parse(mut self, object_block: Pair<'a, Rule>) -> Result<Value> {
if let Some(input_block) = self.input_block.take() {
self.parse_assign_block(input_block).unwrap()
}

let value_block = self.parse_object(object_block)?;
Ok(Value::Object(value_block))
}
Expand Down Expand Up @@ -162,22 +167,19 @@ impl<'a> CornParser<'a> {

/// Parses the `let { } in` block at the start of files,
/// producing a populated HashMap as an output.
fn parse_assign_block(block: Pair<'a, Rule>) -> Result<Inputs> {
fn parse_assign_block(&mut self, block: Pair<'a, Rule>) -> Result<()> {
assert_eq!(block.as_rule(), Rule::assign_block);

let mut inputs = HashMap::new();
let parser = Self::new(None);

for pair in block.into_inner() {
let mut assign_rules = pair.into_inner();
let name = assign_rules.next().unwrap().as_str();

let value = parser.parse_value(assign_rules.next().unwrap())?;
let value = self.parse_value(assign_rules.next().unwrap())?;

inputs.insert(name, value);
self.inputs.insert(name, value);
}

Ok(inputs)
Ok(())
}

/// Attempts to get an input value from the `inputs` map.
Expand Down
23 changes: 13 additions & 10 deletions libcorn/tests/de_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ macro_rules! generate_eq_tests {
let test_name = stringify!($test_name);

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<$test_type>(&input);
let config = from_str::<$test_type>(&input).unwrap();

let json_input = fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
let json_config = serde_json::from_str(&json_input).unwrap();
Expand Down Expand Up @@ -421,6 +421,7 @@ generate_eq_tests!(
(environment_variable, Basic),
(float, Float),
(input, Input),
(input_references_input, Basic),
(integer, Integer),
(mixed_array, MixedArray),
(null, Null),
Expand All @@ -432,12 +433,14 @@ generate_eq_tests!(
(very_compact, Compact)
);

// TODO: Several of these can use the macro, tidy

#[test]
fn basic_new_type_enum() {
let test_name = "basic";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<BasicNewTypeEnum>(&input);
let config = from_str::<BasicNewTypeEnum>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -451,7 +454,7 @@ fn basic_unit_enum() {
let test_name = "basic";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<BasicUnitEnum>(&input);
let config = from_str::<BasicUnitEnum>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -465,7 +468,7 @@ fn basic_new_type() {
let test_name = "basic";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<BasicNewType>(&input);
let config = from_str::<BasicNewType>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -479,7 +482,7 @@ fn bytes() {
let test_name = "basic";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<Bytes>(&input);
let config = from_str::<Bytes>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -493,7 +496,7 @@ fn chained_enum() {
let test_name = "chained";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<ChainedEnum>(&input);
let config = from_str::<ChainedEnum>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -507,7 +510,7 @@ fn mixed_array_enum() {
let test_name = "mixed_array";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<MixedArrayEnum>(&input);
let config = from_str::<MixedArrayEnum>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -521,7 +524,7 @@ fn null_option() {
let test_name = "null";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<NullOption>(&input);
let config = from_str::<NullOption>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -535,7 +538,7 @@ fn null_unit() {
let test_name = "null";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<NullUnit>(&input);
let config = from_str::<NullUnit>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand All @@ -549,7 +552,7 @@ fn str() {
let test_name = "string";

let input = fs::read_to_string(format!("../assets/inputs/{test_name}.corn")).unwrap();
let config = from_str::<Str>(&input);
let config = from_str::<Str>(&input).unwrap();

let json_input =
fs::read_to_string(format!("../assets/outputs/json/{test_name}.json")).unwrap();
Expand Down
1 change: 1 addition & 0 deletions libcorn/tests/parser_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ generate_eq_tests!(
environment_variable,
float,
input,
input_references_input,
integer,
mixed_array,
null,
Expand Down

0 comments on commit 7ea024d

Please sign in to comment.