Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse and resolve ValueReferences #49

Merged
merged 53 commits into from
Mar 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
9ba977f
Refactor Model parser by moving Peekable helper fns into new trait
kellerkindt Mar 3, 2021
9e5b5bd
Parse basic value references ([hex] strings, integers, booleans)
kellerkindt Mar 4, 2021
a719682
Add ITS-Container transformation & build as test case
kellerkindt Mar 5, 2021
cbeead4
Create a new lib-project for testing
kellerkindt Mar 5, 2021
5a5ef42
Add ITS-Container as asn1rs binary test
kellerkindt Mar 5, 2021
339c6d9
github-ci: Fix args for cargo test
kellerkindt Mar 5, 2021
49bc4bf
Link etsi repositories in README for the protocols
kellerkindt Mar 5, 2021
9020273
Add umlaut tests for UTF8String
kellerkindt Mar 8, 2021
6ee2ef4
Add NumericString gh-46
kellerkindt Mar 8, 2021
45fc577
Fix performance regression caused by unnecessary Backtrace instantiat…
kellerkindt Mar 8, 2021
5687d19
Fix UperWriter path in --all-features configuration
kellerkindt Mar 8, 2021
5764264
Add regression stress test for the Tokenizer and Model parser
kellerkindt Mar 11, 2021
1d0092e
Parallelize tests for the GH-CI for fater RTTs after commits
kellerkindt Mar 11, 2021
626aa46
Add note and test for ITS-Container v2 support
kellerkindt Mar 11, 2021
99e430f
Ensure that structs for ITS-Container are generated
kellerkindt Mar 11, 2021
4dd96ec
Actually test the generated file
kellerkindt Mar 11, 2021
9282668
Test the does_it_compile function
kellerkindt Mar 11, 2021
3cc0c8a
Try to test CAM as well
kellerkindt Mar 11, 2021
6b6d900
Replace super paths with crate path
kellerkindt Mar 11, 2021
d0decc2
No need to allocate memory for a vec that is never modified
kellerkindt Mar 11, 2021
abe696c
Fix capcity not depending on the value_references len
kellerkindt Mar 11, 2021
65cacb8
Add support for PrintableString
kellerkindt Mar 11, 2021
9600e4c
Replace map & collect? with try_for_each?
kellerkindt Mar 11, 2021
7150f86
Fix UperWriter mismatch when all features are enabled
kellerkindt Mar 11, 2021
3f028e8
Add NUMERIC_ and IA5_STRING_CHARACTERS and doc-tests
kellerkindt Mar 11, 2021
7af368b
Make Charset::is_valid const
kellerkindt Mar 11, 2021
46aadc1
Add char len assertion for *_STRING_CHARACTERS
kellerkindt Mar 11, 2021
b8e8fdd
Log wrong / bad serialized data as hex
kellerkindt Mar 11, 2021
4d3507c
Add detect_only_invalid_character to basic_ia5string tests
kellerkindt Mar 11, 2021
660fa13
Add support for VisibleString
kellerkindt Mar 11, 2021
50bba95
Add Numeric-, Printable- and VisibleString to the 'Supported Feature'…
kellerkindt Mar 11, 2021
7ba3700
Add cargo tarpaulin for test coverage reports
kellerkindt Mar 11, 2021
09facdd
Use nightly toolchain for tarpaulin
kellerkindt Mar 11, 2021
01dfa68
Activate all features for tarpaulin coverage testing
kellerkindt Mar 11, 2021
20e4fbe
Add tags and hinting for a few more string types
kellerkindt Mar 12, 2021
00b0150
Move model::{protobuf,rust,sql} into their own module-directories
kellerkindt Mar 15, 2021
8ebc98b
Refactor: Split asn1rs::model::mod.rs into smaller files
kellerkindt Mar 15, 2021
65427be
Breaking change! Wrap size-value in size(..) and prepare Size for val…
kellerkindt Mar 15, 2021
38ca29e
Prepare BitString, Integer and Range for unresolved state
kellerkindt Mar 16, 2021
fcb7921
Add Unresolved, Resolved state and Resolver
kellerkindt Mar 16, 2021
08b6241
Resolve variables for SIZE and RANGE values before converting to rust…
kellerkindt Mar 18, 2021
f7cb841
Dont link the raw ITS-Container but the Git view instead
kellerkindt Mar 19, 2021
f4fa8ea
Try add coveralls (thx @MarcoIeni actions-rs/tarpaulin#9)
kellerkindt Mar 19, 2021
f24b8e7
Mention in README that ValueReferences are parsed & resolved in Range…
kellerkindt Mar 19, 2021
f3b4d8c
Add cargo deny to check dependencies for license disagreements
kellerkindt Mar 19, 2021
f8bcf1a
Add runtime-macros hack to include proc macros in coverage report
kellerkindt Mar 19, 2021
68562b7
Explicitly include ans1rs-model/macros for tarpaulin
kellerkindt Mar 19, 2021
20949a2
Finally add workspace section to Cargo.toml
kellerkindt Mar 19, 2021
7b9d02d
Remove package mentions for tarpaulin because this is now a workspace
kellerkindt Mar 19, 2021
f08696b
Relocate proc-macro-coverage-hack to tests and undo workspace setup
kellerkindt Mar 19, 2021
fcb1980
Reparse the result of asn_to_rust! to also track the expansion logic
kellerkindt Mar 19, 2021
ba34570
Add missing visit feature flag to syn
kellerkindt Mar 19, 2021
d05cdc2
Remove manual and unused Default impls
kellerkindt Mar 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 110 additions & 2 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ jobs:
command: check
args: --all-features

test:
name: Test Suite
test-default:
name: Test Suite (default)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand All @@ -34,18 +34,62 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: test

test-protobuf:
name: Test Suite (protobuf)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --features protobuf

test-psql:
name: Test Suite (psql)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --features psql

test-async-psql:
name: Test Suite (async-psql)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --features async-psql

test-all:
name: Test Suite (all)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: actions-rs/cargo@v1
with:
command: test
Expand Down Expand Up @@ -86,3 +130,67 @@ jobs:
with:
command: clippy
args: --all-features -- -D warnings

etsi-standards:
name: ETSI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- run: wget https://forge.etsi.org/rep/ITS/asn1/cdd_ts102894_2/raw/151b191121d05c3b808f5dec14387339730db14f/ITS-Container.asn
- run: wget https://forge.etsi.org/rep/ITS/asn1/cam_en302637_2/raw/7ae4195d48dd468754a50f1a3bb0c2ce976ae15a/CAM-PDU-Descriptions.asn
- uses: actions-rs/cargo@v1
with:
command: run
args: -- tests ITS-Container.asn CAM-PDU-Descriptions.asn
- run: bash -c "echo '#[test] fn does_it_compile() { let _ = StationID(1); }' >> tests/its_container.rs"
- run: sed -i '1i mod its_container;' tests/cam_pdu_descriptions.rs
- run: sed -i 's/super::/crate::/g' tests/cam_pdu_descriptions.rs
- run: cat tests/cam_pdu_descriptions.rs
- run: bash -c "echo '#[test] fn does_it_compile() { let _ = GenerationDeltaTime(1); }' >> tests/cam_pdu_descriptions.rs"
- uses: actions-rs/cargo@v1
with:
command: test
args: --test its_container does_it_compile
- uses: actions-rs/cargo@v1
with:
command: test
args: --test cam_pdu_descriptions does_it_compile

coverage:
name: Test Coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- name: Run cargo-tarpaulin
uses: actions-rs/tarpaulin@v0.1
with:
version: '0.15.0'
args: '--out Xml --out Lcov --all-features -- --test-threads 1'

- name: Archive code coverage results
uses: actions/upload-artifact@v1
with:
name: code-coverage-report
path: cobertura.xml

- name: Upload to Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: './lcov.info'

cargo-deny:
name: Check license and vulnerabilities
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: EmbarkStudios/cargo-deny-action@v1
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ asn1rs-model = { version = "0.2.0", path = "asn1rs-model", optional = true }
asn1rs-macros = { version = "0.2.0", path = "asn1rs-macros", optional = true }

[dev-dependencies]
syn = {version = "1.0.28", features = ["full"] }
syn = {version = "1.0.28", features = ["full", "visit"] }
quote = "1.0.3"
proc-macro2 = "1.0.10"


[features]
default = ["macros", "model"]
psql = ["asn1rs-model/psql", "postgres", "bytes"]
Expand All @@ -71,4 +70,4 @@ path = "benches/bitbuffer.rs"
required-features = ["legacy_bit_buffer"]

[package.metadata.docs.rs]
all-features = true
all-features = true
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,25 @@ The crate can be used as standalone CLI binary or used as library through its AP
| `IA5String` | ✔️ yes | ✔️ yes | ✔️ yes¹ | ✔️ yes¹ | ✔️ yes¹ | ❌ ub |
| ...`SIZE(A..B)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| ...`SIZE(A..B,...)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| `NumericString` | ✔️ yes | ✔️ yes | ✔️ yes¹ | ✔️ yes¹ | ✔️ yes¹ | ❌ ub |
| ...`SIZE(A..B)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| ...`SIZE(A..B,...)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| `PrintableString` | ✔️ yes | ✔️ yes | ✔️ yes¹ | ✔️ yes¹ | ✔️ yes¹ | ❌ ub |
| ...`SIZE(A..B)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| ...`SIZE(A..B,...)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| `VisibleString` | ✔️ yes | ✔️ yes | ✔️ yes¹ | ✔️ yes¹ | ✔️ yes¹ | ❌ ub |
| ...`SIZE(A..B)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| ...`SIZE(A..B,...)` | ✔️ yes | ✔️ yes | 🆗 ignored | 🆗 ignored | 🆗 ignored | ❌ ub |
| `INTEGER` | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes |
| ...`A..B` | ✔️ yes | ✔️ yes | ✔️ yes² | ✔️ yes² | ✔️ yes² | ✔️ yes |
| ...`A..B,...` | ✔️ yes | ✔️ yes | ✔️ yes² | ✔️ yes² | ✔️ yes² | ⚠️ ignored |
| `BOOLEAN` | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes |
| `OPTIONAL` | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes | ✔️ yes |
| `IMPORTS..FROM..;` | ✔️ yes | | | | | |
| `ObjectIdentifiers` | ✔️ yes | | | | | |
| Value References | ✔️ yes | | | | | |
| ... in Range | ✔️ yes | | | | | |
| ... in Size | ✔️ yes | | | | | |


- ✔️ yes: according to specification
Expand All @@ -72,10 +84,12 @@ The crate can be used as standalone CLI binary or used as library through its AP
- The legacy UPER Reader/Writer does not support all features (pre v0.2.0)

#### Supported standards
- [ETSI TS 102 894-2 / ITS-Container](https://www.etsi.org/deliver/etsi_ts/102800_102899/10289402/01.02.01_60/ts_10289402v010201p.pdf): \
```itu-t(0) identified-organization(4) etsi(0) itsDomain(5) wg1(1) ts(102894) cdd(2) version(1)```
- [ETSI EN 302 637-2 / ITS-CAM](https://www.etsi.org/deliver/etsi_en/302600_302699/30263702/01.03.01_30/en_30263702v010301v.pdf): \
```itu-t(0) identified-organization(4) etsi(0) itsDomain(5) wg1(1) en(302637) cam(2) version(1)```
- [📜️ ETSI TS 102 894-2 (PDF)](https://www.etsi.org/deliver/etsi_ts/102800_102899/10289402/01.02.01_60/ts_10289402v010201p.pdf)
/ [🧰 ITS-Container (GIT)](https://forge.etsi.org/rep/ITS/asn1/cdd_ts102894_2/blob/151b191121d05c3b808f5dec14387339730db14f/ITS-Container.asn): \
```itu-t(0) identified-organization(4) etsi(0) itsDomain(5) wg1(1) ts(102894) cdd(2) version(2)```
- [📜️ ETSI EN 302 637-2 (PDF)](https://www.etsi.org/deliver/etsi_en/302600_302699/30263702/01.03.01_30/en_30263702v010301v.pdf)
/ [🧰 CAM-PDU-Description (GIT)](https://forge.etsi.org/rep/ITS/asn1/cam_en302637_2/blob/7ae4195d48dd468754a50f1a3bb0c2ce976ae15a/CAM-PDU-Descriptions.asn): \
```itu-t(0) identified-organization(4) etsi(0) itsDomain(5) wg1(1) en(302637) cam(2) version(2)```

### CLI usage

Expand Down
2 changes: 1 addition & 1 deletion asn1rs-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ debug-proc-macro = []
[dependencies]
asn1rs-model = { version = "0.2.0", path = "../asn1rs-model" }
syn = {version = "1.0.17", features = ["full"] }
quote = "1.0.3"
quote = "1.0.3"
27 changes: 1 addition & 26 deletions asn1rs-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
extern crate proc_macro;

use asn1rs_model::ast;

use asn1rs_model::gen::rust::RustCodeGenerator as RustGenerator;
use asn1rs_model::gen::Generator;
use asn1rs_model::model::Model;
use asn1rs_model::parser::Tokenizer;
use proc_macro::TokenStream;
use syn::parse_macro_input;
use syn::DeriveInput;
Expand All @@ -16,27 +11,7 @@ mod derive_protobuf_eq;
#[proc_macro]
pub fn asn_to_rust(item: TokenStream) -> TokenStream {
let input = parse_macro_input!(item as LitStr).value();
let tokens = Tokenizer::default().parse(&input);
let model = Model::try_from(tokens).unwrap();

let mut generator = RustGenerator::default();
generator.add_model(model.to_rust());

let output = generator
.to_string()
.unwrap()
.into_iter()
.map(|(_file, content)| content)
.collect::<Vec<_>>()
.join("\n");

if cfg!(feature = "debug-proc-macro") {
println!("-------- output start");
println!("{}", output);
println!("-------- output end");
}

output.parse().unwrap()
asn1rs_model::ast::asn_to_rust(&input).parse().unwrap()
}

#[proc_macro_attribute]
Expand Down
51 changes: 35 additions & 16 deletions asn1rs-model/src/ast/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,16 @@ impl<C: Context> Parse for AsnAttribute<C> {
}

fn parse_type<'a>(input: &'a ParseBuffer<'a>) -> syn::Result<Type> {
let ident = input
.step(|c| c.ident().ok_or_else(|| c.error("Expected ASN-Type")))?
.to_string()
.to_lowercase();
let ident = parse_ident(input, "Expected ASN-Type")?.to_lowercase();
parse_type_pre_stepped(&ident, input)
}

fn parse_ident<T: Display>(content: &ParseBuffer, err: T) -> syn::Result<String> {
Ok(content
.step(|c| c.ident().ok_or_else(|| c.error(err)))?
.to_string())
}

fn parse_type_pre_stepped<'a>(
lowercase_ident: &str,
input: &'a ParseBuffer<'a>,
Expand Down Expand Up @@ -150,16 +153,24 @@ fn parse_type_pre_stepped<'a>(
"sequence_of" | "set_of" => {
let content;
parenthesized!(content in input);
let size = if content.peek2(Token![.])
|| (content.peek(Token![-]) && content.peek3(Token![.]))
{
let size = Size::parse(&content)?;

let ident = parse_ident(&content, "Expected size or ASN-Type")?.to_lowercase();

let (size, ident) = if "size".eq(&ident) {
let size_content;
parenthesized!(size_content in content);

let size = Size::parse(&size_content)?;
let _ = content.parse::<token::Comma>()?;
size
let ident = parse_ident(&content, "Expected ASN-Type")?.to_lowercase();

(size, ident)
} else {
Size::Any
(Size::Any, ident)
};
let inner = parse_type(&content)?;

let inner = parse_type_pre_stepped(&ident, &content)?;

if lowercase_ident == "sequence_of" {
Ok(Type::SequenceOf(Box::new(inner), size))
} else {
Expand All @@ -180,7 +191,18 @@ fn parse_opt_size_or_any(input: ParseStream) -> syn::Result<Size> {
if content.is_empty() {
Ok(Size::Any)
} else {
Size::parse(&content)
let ident = parse_ident(&content, "Expected size or ASN-Type")?.to_lowercase();

if "size".eq(&ident) {
let size_content;
parenthesized!(size_content in content);
Size::parse(&size_content)
} else {
Err(input.error(format!(
"Invalid identifier, expected none or size but got: {}",
ident
)))
}
}
}
}
Expand Down Expand Up @@ -297,9 +319,6 @@ impl Deref for DefinitionHeader {
}
impl PrimaryContext for DefinitionHeader {
fn parse(input: &ParseBuffer<'_>) -> syn::Result<Self> {
input
.step(|c| c.ident().ok_or_else(|| c.error("Expected type identifier")))
.map(|ident| ident.to_string())
.map(DefinitionHeader)
parse_ident(input, "Expected type identifier for DefinitionHeader").map(DefinitionHeader)
}
}
31 changes: 31 additions & 0 deletions asn1rs-model/src/ast/inline.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::gen::rust::RustCodeGenerator as RustGenerator;
use crate::gen::Generator;
use crate::model::Model;
use crate::parser::Tokenizer;

pub fn asn_to_rust(input: &str) -> String {
let tokens = Tokenizer::default().parse(&input);
let model = Model::try_from(tokens)
.expect("Failed to parse tokens")
.try_resolve()
.expect("Failed to resolve value references");

let mut generator = RustGenerator::default();
generator.add_model(model.to_rust());

let output = generator
.to_string()
.unwrap()
.into_iter()
.map(|(_file, content)| content)
.collect::<Vec<_>>()
.join("\n");

if cfg!(feature = "debug-proc-macro") {
println!("-------- output start");
println!("{}", output);
println!("-------- output end");
}

output
}
Loading