Skip to content

Commit

Permalink
Support BOOLEAN asn types and rename asn-attribute optional to option #…
Browse files Browse the repository at this point in the history
  • Loading branch information
kellerkindt committed May 4, 2020
1 parent 545fd57 commit 5d79ac9
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 39 deletions.
7 changes: 4 additions & 3 deletions asn1rs-macros/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,8 @@ pub(crate) fn parse(attr: TokenStream, item: TokenStream) -> TokenStream {
if !model.definitions.is_empty() {
let model_rust = model.to_rust();

use asn1rs_model::gen::rust::walker::AsnDefWalker;
let stringified = AsnDefWalker::stringify(&model_rust);
use asn1rs_model::gen::rust::walker::AsnDefExpander;
let stringified = AsnDefExpander::stringify(&model_rust);
additional_impl.push(TokenStream2::from_str(&stringified).unwrap());
}

Expand Down Expand Up @@ -329,12 +329,13 @@ fn parse_type<'a>(input: &'a ParseBuffer<'a>) -> syn::Result<Type> {
Ok(Type::Integer(range.0.map(|(min, max)| Range(min, max))))
}
"complex" => Ok(Type::TypeReference(String::default())),
"optional" => {
"option" => {
let content;
parenthesized!(content in input);
let inner = parse_type(&content)?;
Ok(Type::Optional(Box::new(inner)))
}
"boolean" => Ok(Type::Boolean),
"sequence_of" => {
let content;
parenthesized!(content in input);
Expand Down
55 changes: 22 additions & 33 deletions asn1rs-model/src/gen/rust/walker.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::gen::rust::GeneratorSupplement;
use crate::gen::RustCodeGenerator;
use crate::model::rust::{DataEnum, PlainEnum};
use crate::model::{Definition, Model, Range, Rust, RustType};
Expand All @@ -7,9 +6,9 @@ use std::fmt::Display;

pub const CRATE_SYN_PREFIX: &str = "::asn1rs::syn::";

pub struct AsnDefWalker;
pub struct AsnDefExpander;

impl AsnDefWalker {
impl AsnDefExpander {
fn write_type_definitions(
&self,
scope: &mut Scope,
Expand Down Expand Up @@ -53,7 +52,7 @@ impl AsnDefWalker {
#[must_use]
pub fn type_declaration(r#type: &RustType, name: &str) -> String {
match r#type {
RustType::Bool => format!("{}Bool", CRATE_SYN_PREFIX),
RustType::Bool => format!("{}Boolean", CRATE_SYN_PREFIX),
RustType::I8(_) => format!("{}Integer<i8, {}Constraint>", CRATE_SYN_PREFIX, name),
RustType::U8(_) => format!("{}Integer<u8, {}Constraint>", CRATE_SYN_PREFIX, name),
RustType::I16(_) => format!("{}Integer<i16, {}Constraint>", CRATE_SYN_PREFIX, name),
Expand Down Expand Up @@ -90,7 +89,7 @@ impl AsnDefWalker {
#[must_use]
pub fn combined_field_type_name(base: &str, name: &str) -> String {
format!(
"{}{}",
"{}Field{}",
RustCodeGenerator::rust_variant_name(base),
RustCodeGenerator::rust_variant_name(name)
)
Expand Down Expand Up @@ -447,30 +446,20 @@ impl AsnDefWalker {
let mut scope = Scope::new();
let myself = Self;

myself.add_imports(&mut scope);

for definition in &model.definitions {
myself.impl_supplement(&mut scope, definition);
myself.write_type_definitions(&mut scope, definition);
myself.write_constraints(&mut scope, definition);
myself.impl_readable(&mut scope, &definition.0);
myself.impl_writable(&mut scope, &definition.0);
}

scope.to_string()
}
}

impl GeneratorSupplement<Rust> for AsnDefWalker {
fn add_imports(&self, _scope: &mut Scope) {}

fn impl_supplement(&self, scope: &mut Scope, definition: &Definition<Rust>) {
self.write_type_definitions(scope, definition);
self.write_constraints(scope, definition);
self.impl_readable(scope, &definition.0);
self.impl_writable(scope, &definition.0);
}
}

#[cfg(test)]
pub mod tests {
use crate::gen::rust::walker::AsnDefWalker;
use crate::gen::rust::walker::AsnDefExpander;
use crate::model::{Definition, Rust, RustType};
use codegen::Scope;

Expand All @@ -495,7 +484,7 @@ pub mod tests {
pub fn test_whatever_struct_type_declaration() {
let def = simple_whatever_sequence();
let mut scope = Scope::new();
AsnDefWalker.write_type_definitions(&mut scope, &def);
AsnDefExpander.write_type_definitions(&mut scope, &def);
let string = scope.to_string();
println!("{}", string);
let mut lines = string.lines().filter(|l| !l.is_empty());
Expand All @@ -504,15 +493,15 @@ pub mod tests {
lines.next()
);
assert_eq!(
Some("type AsnDefWhateverName = ::asn1rs::syn::Utf8String;"),
Some("type AsnDefWhateverFieldName = ::asn1rs::syn::Utf8String;"),
lines.next()
);
assert_eq!(
Some("type AsnDefWhateverOpt = Option<::asn1rs::syn::Utf8String>;"),
Some("type AsnDefWhateverFieldOpt = Option<::asn1rs::syn::Utf8String>;"),
lines.next()
);
assert_eq!(
Some("type AsnDefWhateverSome = Option<::asn1rs::syn::Utf8String>;"),
Some("type AsnDefWhateverFieldSome = Option<::asn1rs::syn::Utf8String>;"),
lines.next()
);
}
Expand All @@ -521,9 +510,9 @@ pub mod tests {
pub fn test_whatever_struct_constraint_and_read_write_impl() {
let def = simple_whatever_sequence();
let mut scope = Scope::new();
AsnDefWalker.write_constraints(&mut scope, &def);
AsnDefWalker.impl_readable(&mut scope, &def.0);
AsnDefWalker.impl_writable(&mut scope, &def.0);
AsnDefExpander.write_constraints(&mut scope, &def);
AsnDefExpander.impl_readable(&mut scope, &def.0);
AsnDefExpander.impl_writable(&mut scope, &def.0);
let string = scope.to_string();
println!("{}", string);

Expand Down Expand Up @@ -551,16 +540,16 @@ pub mod tests {
where Self: Sized,
{
Ok(Self {
name: AsnDefWhateverName::read_value(reader)?,
opt: AsnDefWhateverOpt::read_value(reader)?,
some: AsnDefWhateverSome::read_value(reader)?,
name: AsnDefWhateverFieldName::read_value(reader)?,
opt: AsnDefWhateverFieldOpt::read_value(reader)?,
some: AsnDefWhateverFieldSome::read_value(reader)?,
})
}
fn write_seq<W: ::asn1rs::syn::Writer>(&self, writer: &mut W) -> Result<(), W::Error> {
AsnDefWhateverName::write_value(writer, &self.name)?;
AsnDefWhateverOpt::write_value(writer, &self.opt)?;
AsnDefWhateverSome::write_value(writer, &self.some)?;
AsnDefWhateverFieldName::write_value(writer, &self.name)?;
AsnDefWhateverFieldOpt::write_value(writer, &self.opt)?;
AsnDefWhateverFieldSome::write_value(writer, &self.some)?;
Ok(())
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/syn/boolean.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use crate::syn::{ReadableType, Reader, WritableType, Writer};
use core::marker::PhantomData;

pub struct Boolean<C: Constraint = NoConstraint>(PhantomData<C>);

impl<C: Constraint> Default for Boolean<C> {
fn default() -> Self {
Boolean(Default::default())
}
}

pub trait Constraint {}

#[derive(Default)]
pub struct NoConstraint;
impl Constraint for NoConstraint {}

impl<C: Constraint> WritableType for Boolean<C> {
type Type = bool;

fn write_value<W: Writer>(
writer: &mut W,
value: &Self::Type,
) -> Result<(), <W as Writer>::Error> {
writer.write_boolean::<C>(*value)
}
}

impl<C: Constraint> ReadableType for Boolean<C> {
type Type = bool;

fn read_value<R: Reader>(reader: &mut R) -> Result<Self::Type, <R as Reader>::Error> {
reader.read_boolean::<C>()
}
}
5 changes: 5 additions & 0 deletions src/syn/io/println.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,9 @@ impl Writer for PrintlnWriter {
self.indented_println(format!("WRITING OctetString {:?}", value));
Ok(())
}

fn write_boolean<C: boolean::Constraint>(&mut self, value: bool) -> Result<(), Self::Error> {
self.indented_println(format!("WRITING Boolean {}", value));
Ok(())
}
}
8 changes: 8 additions & 0 deletions src/syn/io/uper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ impl Writer for UperWriter {
self.buffer
.write_octet_string(value, bit_buffer_range::<C>())
}

fn write_boolean<C: boolean::Constraint>(&mut self, value: bool) -> Result<(), Self::Error> {
self.buffer.write_bit(value)
}
}

pub struct UperReader {
Expand Down Expand Up @@ -335,6 +339,10 @@ impl Reader for UperReader {
fn read_octet_string<C: octetstring::Constraint>(&mut self) -> Result<Vec<u8>, Self::Error> {
self.buffer.read_octet_string(bit_buffer_range::<C>())
}

fn read_boolean<C: boolean::Constraint>(&mut self) -> Result<bool, Self::Error> {
self.buffer.read_bit()
}
}

fn bit_buffer_range<C: octetstring::Constraint>() -> Option<(i64, i64)> {
Expand Down
6 changes: 6 additions & 0 deletions src/syn/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::marker::PhantomData;

pub mod boolean;
pub mod choice;
pub mod complex;
pub mod enumerated;
Expand All @@ -11,6 +12,7 @@ pub mod sequence;
pub mod sequenceof;
pub mod utf8string;

pub use boolean::Boolean;
pub use choice::Choice;
pub use complex::Complex;
pub use enumerated::Enumerated;
Expand Down Expand Up @@ -56,6 +58,8 @@ pub trait Reader {
fn read_utf8string<C: utf8string::Constraint>(&mut self) -> Result<String, Self::Error>;

fn read_octet_string<C: octetstring::Constraint>(&mut self) -> Result<Vec<u8>, Self::Error>;

fn read_boolean<C: boolean::Constraint>(&mut self) -> Result<bool, Self::Error>;
}

pub trait Readable: Sized {
Expand Down Expand Up @@ -122,6 +126,8 @@ pub trait Writer {
&mut self,
value: &[u8],
) -> Result<(), Self::Error>;

fn write_boolean<C: boolean::Constraint>(&mut self, value: bool) -> Result<(), Self::Error>;
}

pub trait Writable {
Expand Down
34 changes: 31 additions & 3 deletions tests/basic_proc_macro_attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ fn are_we_binary_yet_uper() {
#[asn(sequence)]
#[derive(Debug, PartialOrd, PartialEq)]
pub struct Optional {
#[asn(optional(integer))]
#[asn(option(integer))]
value: Option<u64>,
}

Expand All @@ -273,7 +273,7 @@ fn test_optional_uper() {
#[asn(sequence)]
#[derive(Debug, PartialOrd, PartialEq)]
pub struct CrazyList {
#[asn(sequence_of(optional(optional(sequence_of(integer)))))]
#[asn(sequence_of(option(option(sequence_of(integer)))))]
values: Vec<Option<Option<Vec<u64>>>>,
}

Expand Down Expand Up @@ -387,7 +387,7 @@ fn test_flat_list_uper() {

#[asn(transparent)]
#[derive(Debug, PartialOrd, PartialEq)]
pub struct Important(#[asn(optional(integer))] Option<u64>);
pub struct Important(#[asn(option(integer))] Option<u64>);

#[test]
fn test_transparent_important_println() {
Expand Down Expand Up @@ -442,3 +442,31 @@ fn test_transparent_important_uper_none() {
assert_eq!(v, uper.read::<Important>().unwrap());
assert_eq!(0, uper.bits_remaining());
}

#[asn(sequence)]
#[derive(Debug, Default, PartialOrd, PartialEq)]
pub struct BoolContainer {
#[asn(boolean)]
bool1: bool,
#[asn(boolean)]
bool2: bool,
#[asn(boolean)]
bool3: bool,
}

#[test]
fn test_bool_container_uper() {
let mut uper = UperWriter::default();
let v = BoolContainer {
bool1: false,
bool2: true,
bool3: true,
};
uper.write(&v).unwrap();
assert_eq!(&[0b011_0_0000], uper.byte_content());
assert_eq!(3, uper.bit_len());

let mut uper = uper.into_reader();
assert_eq!(v, uper.read::<BoolContainer>().unwrap());
assert_eq!(0, uper.bits_remaining());
}

0 comments on commit 5d79ac9

Please sign in to comment.