Skip to content

Commit

Permalink
more implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
anweiss committed Oct 20, 2022
1 parent 4616bd6 commit 49f7e8a
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 2 deletions.
32 changes: 31 additions & 1 deletion src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{
#[cfg(feature = "std")]
use std::borrow::Cow;

#[cfg(any(target_arch = "wasm32"))]
#[cfg(target_arch = "wasm32")]
use serde::{self, Serialize};

#[cfg(not(feature = "std"))]
Expand Down Expand Up @@ -79,6 +79,18 @@ impl<'a, 'b: 'a> From<&'b GroupRule<'a>> for CDDLType<'a, 'b> {
}
}

impl<'a, 'b: 'a> From<&'b Group<'a>> for CDDLType<'a, 'b> {
fn from(group: &'b Group<'a>) -> Self {
CDDLType::Group(group)
}
}

impl<'a, 'b: 'a> From<&'b GroupChoice<'a>> for CDDLType<'a, 'b> {
fn from(group_choice: &'b GroupChoice<'a>) -> Self {
CDDLType::GroupChoice(group_choice)
}
}

impl<'a, 'b: 'a> From<&'b Identifier<'a>> for CDDLType<'a, 'b> {
fn from(ident: &'b Identifier<'a>) -> Self {
CDDLType::Identifier(ident)
Expand Down Expand Up @@ -139,6 +151,24 @@ impl<'a, 'b: 'a> From<&'b GenericParam<'a>> for CDDLType<'a, 'b> {
}
}

impl<'a, 'b: 'a> From<&'b GenericArgs<'a>> for CDDLType<'a, 'b> {
fn from(args: &'b GenericArgs<'a>) -> Self {
CDDLType::GenericArgs(args)
}
}

impl<'a, 'b: 'a> From<&'b GenericArg<'a>> for CDDLType<'a, 'b> {
fn from(arg: &'b GenericArg<'a>) -> Self {
CDDLType::GenericArg(arg)
}
}

impl<'a, 'b: 'a> From<&'b Operator<'a>> for CDDLType<'a, 'b> {
fn from(operator: &'b Operator<'a>) -> Self {
CDDLType::Operator(operator)
}
}

#[cfg(feature = "ast-comments")]
#[derive(Default, Debug, PartialEq, Eq, Clone)]
#[doc(hidden)]
Expand Down
91 changes: 90 additions & 1 deletion src/validator/parent_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,46 @@ impl<'a, 'b: 'a> Parent<'a, 'b, GenericParams<'a>> for GenericParam<'a> {
}
}

impl<'a, 'b: 'a> Parent<'a, 'b, Type2<'a>> for GenericArgs<'a> {
fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&Type2<'a>> {
if let Some(CDDLType::Type2(t2)) = CDDLType::from(self).parent(parent_visitor) {
return Some(t2);
}

None
}
}

impl<'a, 'b: 'a> Parent<'a, 'b, GenericArgs<'a>> for GenericArg<'a> {
fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&GenericArgs<'a>> {
if let Some(CDDLType::GenericArgs(args)) = CDDLType::from(self).parent(parent_visitor) {
return Some(args);
}

None
}
}

impl<'a, 'b: 'a> Parent<'a, 'b, Type1<'a>> for Operator<'a> {
fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&Type1<'a>> {
if let Some(CDDLType::Type1(t1)) = CDDLType::from(self).parent(parent_visitor) {
return Some(t1);
}

None
}
}

impl<'a, 'b: 'a> Parent<'a, 'b, Type2<'a>> for Type<'a> {
fn parent(&'a self, parent_visitor: &'b ParentVisitor<'a, 'b>) -> Option<&Type2<'a>> {
if let Some(CDDLType::Type2(t2)) = CDDLType::from(self).parent(parent_visitor) {
return Some(t2);
}

None
}
}

#[derive(Debug, Default, Clone)]
struct ArenaTree<'a, 'b: 'a> {
arena: Vec<Node<'a, 'b>>,
Expand Down Expand Up @@ -789,7 +829,8 @@ mod tests {
let pv = ParentVisitor::new(&cddl).unwrap();

if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
assert_eq!(rule.value.parent(&pv).unwrap(), rule);
let parent: &TypeRule = rule.value.parent(&pv).unwrap();
assert_eq!(parent, rule);
}

Ok(())
Expand Down Expand Up @@ -938,4 +979,52 @@ mod tests {

Ok(())
}

#[test]
fn generic_args_parent_is_type2() -> Result<()> {
let cddl = cddl_from_str(
r#"
messages = message<"reboot", "now"> / message<"sleep", 1..100>
"#,
true,
)
.unwrap();
let pv = ParentVisitor::new(&cddl).unwrap();

if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
if let t2 @ Type2::Typename {
generic_args: Some(ga),
..
} = &rule.value.type_choices.first().unwrap().type1.type2
{
assert_eq!(ga.parent(&pv).unwrap(), t2);
}
}

Ok(())
}

#[test]
fn generic_arg_parent_is_generic_args() -> Result<()> {
let cddl = cddl_from_str(
r#"
messages = message<"reboot", "now"> / message<"sleep", 1..100>
"#,
true,
)
.unwrap();
let pv = ParentVisitor::new(&cddl).unwrap();

if let Rule::Type { rule, .. } = cddl.rules.first().unwrap() {
if let Type2::Typename {
generic_args: Some(ga),
..
} = &rule.value.type_choices.first().unwrap().type1.type2
{
assert_eq!(ga.args.first().unwrap().parent(&pv).unwrap(), ga);
}
}

Ok(())
}
}

0 comments on commit 49f7e8a

Please sign in to comment.