Skip to content

Commit

Permalink
Properly parse negative range values, expect the type for complex asn…
Browse files Browse the repository at this point in the history
…-attributes #11
  • Loading branch information
kellerkindt committed May 4, 2020
1 parent 5d79ac9 commit 7de0269
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 15 deletions.
8 changes: 7 additions & 1 deletion asn1rs-macros/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,13 @@ fn parse_type<'a>(input: &'a ParseBuffer<'a>) -> syn::Result<Type> {
let range = MaybeRanged::parse(input)?;
Ok(Type::Integer(range.0.map(|(min, max)| Range(min, max))))
}
"complex" => Ok(Type::TypeReference(String::default())),
"complex" => {
let content;
parenthesized!(content in input);
let ident =
content.step(|c| c.ident().ok_or_else(|| c.error("Expected type identifier")))?;
Ok(Type::TypeReference(ident.to_string()))
}
"option" => {
let content;
parenthesized!(content in input);
Expand Down
42 changes: 31 additions & 11 deletions asn1rs-macros/src/ast/range.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use proc_macro2::Delimiter;
use syn::parse::{Parse, ParseBuffer};
use syn::buffer::Cursor;
use syn::parse::{Parse, ParseBuffer, StepCursor};

pub struct MaybeRanged(pub Option<(i64, i64)>);

Expand All @@ -11,20 +12,12 @@ impl Parse for MaybeRanged {
.group(Delimiter::Parenthesis)
.ok_or_else(|| stepper.error("Expected range"))?;

let (min, c) = a
.ident()
.map(|(a, b)| (a.to_string(), b))
.or_else(|| a.literal().map(|(a, b)| (a.to_string(), b)))
.ok_or_else(|| stepper.error("Expected min value"))?;
let (min, c) = number_potentially_negative(&stepper, a, "Expected min value")?;

let (_, c) = c.punct().ok_or_else(|| stepper.error("Expected dot"))?;
let (_, c) = c.punct().ok_or_else(|| stepper.error("Expected dot"))?;

let (max, _c) = c
.ident()
.map(|(a, b)| (a.to_string(), b))
.or_else(|| c.literal().map(|(a, b)| (a.to_string(), b)))
.ok_or_else(|| stepper.error("Expected max value"))?;
let (max, _c) = number_potentially_negative(&stepper, c, "Expected max value")?;

let min = min.to_lowercase();
let max = max.to_lowercase();
Expand All @@ -42,3 +35,30 @@ impl Parse for MaybeRanged {
}
}
}

fn number_potentially_negative<'a>(
stepper: &'a StepCursor<'_, 'a>,
a: Cursor<'a>,
err: &str,
) -> Result<(String, Cursor<'a>), syn::Error> {
let (min, c) = ident_or_literal_or_punct(&stepper, a, err)?;
println!("NUMBER v1 : {}", min);
if min == "-" {
let (min, c) = ident_or_literal_or_punct(&stepper, c, err)?;
Ok((format!("-{}", min), c))
} else {
Ok((min, c))
}
}

fn ident_or_literal_or_punct<'a>(
stepper: &'a StepCursor<'_, 'a>,
a: Cursor<'a>,
err: &str,
) -> Result<(String, Cursor<'a>), syn::Error> {
a.ident()
.map(|(a, b)| (a.to_string(), b))
.or_else(|| a.literal().map(|(a, b)| (a.to_string(), b)))
.or_else(|| a.punct().map(|(a, b)| (a.to_string(), b)))
.ok_or_else(|| stepper.error(err))
}
10 changes: 7 additions & 3 deletions tests/basic_proc_macro_attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fn topping_test_deserialize_with_uper() {
pub struct Pizza {
#[asn(integer(1..4))]
size: u8,
#[asn(complex)]
#[asn(complex(Topping))]
topping: Topping,
}

Expand Down Expand Up @@ -152,9 +152,9 @@ fn pizza_test_uper_3() {
#[asn(choice)]
#[derive(Debug, PartialOrd, PartialEq)]
pub enum WhatToEat {
#[asn(complex)]
#[asn(complex(Potato))]
Potato(Potato),
#[asn(complex)]
#[asn(complex(Pizza))]
Pizza(Pizza),
}

Expand Down Expand Up @@ -470,3 +470,7 @@ fn test_bool_container_uper() {
assert_eq!(v, uper.read::<BoolContainer>().unwrap());
assert_eq!(0, uper.bits_remaining());
}

#[asn(transparent)]
#[derive(Debug, Default, PartialOrd, PartialEq)]
pub struct NegativeRangeMin(#[asn(integer(- 12..12))] i8);

0 comments on commit 7de0269

Please sign in to comment.