Skip to content

Commit 2c1f1b7

Browse files
committed
Merge branch 'main' into naming
2 parents 068f27f + c088b4c commit 2c1f1b7

26 files changed

+12412
-1597
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
exclude: |
44
(?x)^(
55
.+\.(dbc|DBC)
6-
| .*/docs/diagram\.svg
6+
| docs/diagram\.svg
77
)$
88
99
repos:

Cargo.toml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,16 @@ edition = "2021"
1111
rust-version = "1.74"
1212

1313
[features]
14-
default = ["with-serde"]
15-
with-serde = ["dep:serde"]
14+
default = ["with-serde", "encodings"]
15+
# Support decoding from all standard encodings, e.g. cp1251 commonly used for dbc
16+
encodings = ["dep:encoding_rs"]
17+
serde = ["dep:serde"]
18+
# This feature is deprecated per clippy::redundant_feature_names. Use `serde` instead.
19+
with-serde = ["serde"]
1620

1721
[dependencies]
1822
derive-getters = "0.5"
23+
encoding_rs = { version = "0.8", optional = true }
1924
nom = { version = "8.0", features = ["alloc"] }
2025
serde = { version = "1.0", features = ["derive"], optional = true }
2126

@@ -31,18 +36,12 @@ unused_qualifications = "warn"
3136
[lints.clippy]
3237
cargo = { level = "warn", priority = -1 }
3338
pedantic = { level = "warn", priority = -1 }
39+
# Verified allows
40+
ref_option = "allow" # required by derive-getters
41+
redundant_feature_names = "allow" # remove once with-serde feature is removed
42+
needless_doctest_main = "allow" # README code block contains main function
3443
# TODO: fix these if it makes sense
35-
doc_markdown = "allow" # 36
3644
must_use_candidate = "allow" # 12
3745
missing_errors_doc = "allow" # 8
3846
similar_names = "allow" # 4
39-
redundant_feature_names = "allow" # 4
4047
needless_pass_by_value = "allow" # 4
41-
cargo_common_metadata = "allow" # 4
42-
upper_case_acronyms = "allow" # 2
43-
trivially_copy_pass_by_ref = "allow" # 2
44-
ref_option = "allow" # 2
45-
match_wildcard_for_single_variants = "allow" # 2
46-
cast_possible_truncation = "allow" # 2
47-
match_same_arms = "allow" # 1
48-
items_after_test_module = "allow" # 1

README.md

Lines changed: 56 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -10,111 +10,97 @@
1010

1111
A CAN-dbc format parser written with Rust's [nom](https://github.com/Geal/nom) parser combinator library. CAN databases are used to exchange details about a CAN network, e.g. what messages are being send over the CAN bus and what data do they contain.
1212

13-
# 1. Example
13+
## Usage example
1414

1515
Read dbc file and generate Rust structs based on the messages/signals defined in the dbc.
1616

1717
```rust,no_run
18-
use can_dbc::DBC;
18+
use std::fs;
19+
use can_dbc::Dbc;
1920
use codegen::Scope;
2021
21-
use std::fs::File;
22-
use std::io;
23-
use std::io::prelude::*;
24-
25-
fn main() -> io::Result<()> {
26-
let mut f = File::open("./examples/sample.dbc")?;
27-
let mut buffer = Vec::new();
28-
f.read_to_end(&mut buffer)?;
29-
30-
let dbc = can_dbc::DBC::from_slice(&buffer).expect("Failed to parse dbc file");
22+
fn main() {
23+
let data = fs::read_to_string("./examples/sample.dbc").expect("Unable to read input file");
24+
let dbc = Dbc::try_from(data.as_str()).expect("Failed to parse dbc file");
3125
3226
let mut scope = Scope::new();
33-
for message in dbc.messages() {
34-
for signal in message.signals() {
35-
36-
let mut scope = Scope::new();
37-
let message_struct = scope.new_struct(message.name());
38-
for signal in message.signals() {
39-
message_struct.field(signal.name().to_lowercase().as_str(), "f64");
40-
}
27+
for msg in dbc.messages() {
28+
let msg_struct = scope.new_struct(msg.name());
29+
for signal in msg.signals() {
30+
msg_struct.field(signal.name().to_lowercase().as_str(), "f64");
4131
}
4232
}
4333
4434
println!("{}", scope.to_string());
45-
Ok(())
4635
}
4736
```
4837

4938
For a proper implementation for reading or writing CAN frames according to the DBC, I recommend you take a look at [dbc-codegen](https://github.com/technocreatives/dbc-codegen).
5039

51-
# 2. Example
40+
## Running Parser Example
5241

5342
The file parser simply parses a dbc input file and prints the parsed content.
5443

5544
```bash
56-
cargo test && ./target/debug/examples/file_parser -i examples/sample.dbc
57-
```
58-
59-
# Installation
60-
can-dbc is available on crates.io and can be included in your Cargo enabled project like this:
61-
62-
```toml
63-
[dependencies]
64-
can-dbc = "3.0"
45+
cargo run --example file_parser -- --input examples/sample.dbc
6546
```
6647

6748
# Structure
6849

6950
![Diagram](./docs/diagram.svg)
7051

71-
72-
# Implemented DBC parts
73-
74-
- [x] version
75-
- [x] new_symbols
76-
- [x] bit_timing *(deprecated but mandatory)*
77-
- [x] nodes
78-
- [x] value_tables
79-
- [x] messages
80-
- [x] message_transmitters
81-
- [x] environment_variables
82-
- [x] environment_variables_data
83-
- [x] signal_types
84-
- [x] comments
85-
- [x] attribute_definitions
86-
- [ ] sigtype_attr_list *(format missing documentation)*
87-
- [x] attribute_defaults
88-
- [x] attribute_values
89-
- [x] value_descriptions
90-
- [ ] category_definitions *(deprecated)*
91-
- [ ] categories *(deprecated)*
92-
- [ ] filter *(deprecated)*
93-
- [x] signal_type_refs
94-
- [x] signal_groups
95-
- [x] signal_extended_value_type_list
96-
97-
# Deviating from standard
52+
## Implemented DBC parts
53+
54+
- [x] `version`
55+
- [x] `new_symbols`
56+
- [x] `bit_timing` *(deprecated but mandatory)*
57+
- [x] `nodes`
58+
- [x] `value_tables`
59+
- [x] `messages`
60+
- [x] `message_transmitters`
61+
- [x] `environment_variables`
62+
- [x] `environment_variables_data`
63+
- [x] `signal_types`
64+
- [x] `comments`
65+
- [x] `attribute_definitions`
66+
- [ ] `sigtype_attr_list` *(format missing documentation)*
67+
- [x] `attribute_defaults`
68+
- [x] `attribute_values`
69+
- [x] `value_descriptions`
70+
- [ ] `category_definitions` *(deprecated)*
71+
- [ ] `categories` *(deprecated)*
72+
- [ ] `filter` *(deprecated)*
73+
- [x] `signal_type_refs`
74+
- [x] `signal_groups`
75+
- [x] `signal_extended_value_type_list`
76+
77+
### Deviating from standard
9878
- multispace between parsers instead of single space allowing e.g. (two spaces) `SIG_GROUP 13`.
9979
- `VAL_` suffix may be ` ;` or `;`
10080

101-
# Alternatives
81+
## Alternatives
10282
- [canparse](https://github.com/jmagnuson/canparse)
10383

104-
# Credits
84+
## Credits
10585
Test dbcs files were copied from the [cantools](https://github.com/eerimoq/cantools) project.
10686

107-
# License Checks
108-
109-
This project uses [cargo-deny](https://github.com/EmbarkStudios/cargo-deny) for checking the licenses of dependencies. To run the check locally run the following:
110-
111-
```bash
112-
cargo install cargo-deny
113-
cargo deny check
114-
```
115-
116-
# Development
87+
## Development
11788
* This project is easier to develop with [just](https://just.systems/man/en/), a modern alternative to `make`.
11889
* To get a list of available commands, run `just`.
11990
* To run tests, use `just test`.
12091
* This project uses [insta](https://insta.rs) for snapshot testing. To update the snapshots run `just bless`
92+
93+
## License
94+
95+
Licensed under either of
96+
97+
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)
98+
* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/licenses/MIT>)
99+
at your option.
100+
101+
### Contribution
102+
103+
Unless you explicitly state otherwise, any contribution intentionally
104+
submitted for inclusion in the work by you, as defined in the
105+
Apache-2.0 license, shall be dual-licensed as above, without any
106+
additional terms or conditions.

deny.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# [possible values: any SPDX 3.11 short identifier (+ optional exception)].
88
allow = [
99
"Apache-2.0",
10+
"BSD-3-Clause",
1011
"MIT",
1112
"Unicode-3.0",
1213
]

examples/file_parser.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,48 @@
1+
use std::borrow::Cow;
12
use std::convert::TryFrom;
2-
use std::fs::File;
3-
use std::io;
4-
use std::io::prelude::*;
3+
use std::fs;
4+
use std::str::from_utf8;
55

6+
use can_dbc::encodings::Encoding;
7+
use can_dbc::{Dbc, Error};
68
use clap::Parser;
79

810
#[derive(Parser)]
911
#[command(about, version)]
1012
struct Args {
13+
/// Input file encoding. If not specified, UTF-8 is assumed.
14+
#[arg(short, long, default_value = "utf-8")]
15+
encoding: Option<String>,
16+
1117
/// DBC file path
12-
#[arg(
13-
short,
14-
long,
15-
default_value = "./examples/sample.dbc",
16-
value_name = "FILE"
17-
)]
18+
#[arg(default_value = "./examples/sample.dbc", value_name = "FILE")]
1819
input: String,
1920
}
2021

21-
fn main() -> io::Result<()> {
22+
fn main() {
2223
let args = Args::parse();
2324
let path = &args.input;
2425

25-
let mut f = File::open(path)?;
26-
let mut buffer = Vec::new();
27-
f.read_to_end(&mut buffer)?;
28-
let dbc_in = std::str::from_utf8(&buffer).unwrap();
26+
let data = fs::read(path).expect("Unable to read input file");
27+
28+
let data = if let Some(enc) = &args.encoding {
29+
let enc = Encoding::for_label(enc.as_bytes()).expect("Unknown encoding");
30+
enc.decode_without_bom_handling_and_without_replacement(&data)
31+
.expect("Unable to decode using specified encoding")
32+
} else {
33+
let data = from_utf8(&data).expect("Input file is not valid UTF-8. Consider specifying the encoding with the --encoding option.");
34+
Cow::Borrowed(data)
35+
};
2936

30-
match can_dbc::DBC::try_from(dbc_in) {
31-
Ok(dbc_content) => println!("DBC Content{dbc_content:#?}"),
37+
match Dbc::try_from(data.as_ref()) {
38+
Ok(dbc_content) => println!("{dbc_content:#?}"),
3239
Err(e) => {
3340
match e {
34-
can_dbc::Error::Nom(nom::Err::Error(e) | nom::Err::Failure(e)) => eprintln!("{e:?}"),
35-
can_dbc::Error::Nom(nom::Err::Incomplete(needed)) => eprintln!("Nom incomplete needed: {needed:#?}"),
36-
can_dbc::Error::Incomplete(dbc, remaining) => eprintln!("Not all data in buffer was read {dbc:#?}, remaining unparsed (length: {}): {remaining}\n...(truncated)", remaining.len()),
37-
can_dbc::Error::MultipleMultiplexors => eprintln!("Multiple multiplexors defined"),
38-
can_dbc::Error::InvalidContent(e) => eprintln!("Invalid content: {e:?}"),
41+
Error::Nom(nom::Err::Error(e) | nom::Err::Failure(e)) => eprintln!("{e:?}"),
42+
Error::Nom(nom::Err::Incomplete(needed)) => eprintln!("Nom incomplete needed: {needed:#?}"),
43+
Error::Incomplete(dbc, remaining) => eprintln!("Not all data in buffer was read {dbc:#?}, remaining unparsed (length: {}): {remaining}\n...(truncated)", remaining.len()),
44+
Error::MultipleMultiplexors => eprintln!("Multiple multiplexors defined"),
3945
}
4046
}
4147
}
42-
43-
Ok(())
4448
}

justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ ci_mode := if env('CI', '') != '' {'1'} else {''}
1414
binstall_args := if env('CI', '') != '' {'--no-confirm --no-track --disable-telemetry'} else {''}
1515
export RUSTFLAGS := env('RUSTFLAGS', if ci_mode == '1' {'-D warnings'} else {''})
1616
export RUSTDOCFLAGS := env('RUSTDOCFLAGS', if ci_mode == '1' {'-D warnings'} else {''})
17-
export RUST_BACKTRACE := env('RUST_BACKTRACE', if ci_mode == '1' {'1'} else {''})
17+
export RUST_BACKTRACE := env('RUST_BACKTRACE', if ci_mode == '1' {'1'} else {'0'})
1818

1919
@_default:
2020
{{just_executable()}} --list

0 commit comments

Comments
 (0)