Skip to content

Commit fab3965

Browse files
committed
wip
1 parent 371e95e commit fab3965

File tree

8 files changed

+2368
-351
lines changed

8 files changed

+2368
-351
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ serde = ["dep:serde"]
2424
with-serde = ["serde"]
2525

2626
[dependencies]
27-
can-dbc-pest = { version = "0.5.1" }
27+
can-dbc-pest = { version = "0.6.0" }
2828
encoding_rs = { version = "0.8", optional = true }
2929
serde = { version = "1.0", features = ["derive"], optional = true }
3030
thiserror = "2.0.17"
@@ -57,5 +57,5 @@ cast_precision_loss = "allow"
5757
too_many_lines = "allow"
5858
missing_panics_doc = "allow"
5959

60-
[patch.crates-io]
61-
can-dbc-pest = { path = "../can-dbc-pest" }
60+
#[patch.crates-io]
61+
#can-dbc-pest = { path = "../can-dbc-pest" }

src/ast/comment.rs

Lines changed: 51 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use can_dbc_pest::{Pair, Pairs, Rule};
22

33
use crate::ast::MessageId;
4-
use crate::parser::{inner_str, next, next_rule, validated_inner, DbcError};
4+
use crate::parser::{
5+
inner_str, next, next_optional_rule, next_rule, next_string, single_inner, validated_inner,
6+
DbcError,
7+
};
58

69
/// Object comments
710
#[derive(Clone, Debug, PartialEq)]
@@ -38,94 +41,59 @@ impl TryFrom<Pair<'_, Rule>> for Comment {
3841

3942
let pair = next(&mut inner_pairs)?;
4043

41-
match pair.as_rule() {
42-
Rule::comment_signal => parse_signal_comment(pair),
43-
Rule::comment_message | Rule::comment_message_implicit => parse_message_comment(pair),
44-
Rule::comment_node => parse_node_comment(pair),
45-
Rule::comment_env_var => parse_env_var_comment(pair),
46-
Rule::comment_plain => parse_plain_comment(pair),
47-
rule => Err(DbcError::UnknownRule(rule)),
44+
if pair.as_rule() == Rule::comment_plain {
45+
// Parse plain comment: `"comment"`
46+
let comment = inner_str(single_inner(pair, Rule::quoted_str)?);
47+
Ok(Comment::Plain { comment })
48+
} else {
49+
let rule = pair.as_rule();
50+
let mut inner = pair.into_inner();
51+
match rule {
52+
Rule::comment_signal => parse_signal_comment(inner),
53+
Rule::comment_message | Rule::comment_message_implicit => {
54+
// Parse message comment: `BO_ <message_id> "comment"`
55+
// implicit comment: `<message_id> "comment"`
56+
Ok(Comment::Message {
57+
id: next_rule(&mut inner, Rule::message_id)?.try_into()?,
58+
comment: inner_str(next_rule(&mut inner, Rule::quoted_str)?),
59+
})
60+
}
61+
Rule::comment_node => {
62+
// Parse node comment: `BU_ <node_name> "comment"`
63+
Ok(Comment::Node {
64+
name: next_string(&mut inner, Rule::node_name)?,
65+
comment: inner_str(next_rule(&mut inner, Rule::quoted_str)?),
66+
})
67+
}
68+
Rule::comment_env_var => {
69+
// Parse environment variable comment: `EV_ <env_var_name> "comment"`
70+
Ok(Comment::EnvVar {
71+
name: next_string(&mut inner, Rule::env_var_name)?,
72+
comment: inner_str(next_rule(&mut inner, Rule::quoted_str)?),
73+
})
74+
}
75+
rule => Err(DbcError::UnknownRule(rule)),
76+
}
4877
}
4978
}
5079
}
5180

5281
/// Parse signal comment: `SG_ <message_id> [<signal_name>] "comment"`
5382
/// If signal_name is omitted, this is treated as a message comment.
54-
fn parse_signal_comment(pair: Pair<'_, Rule>) -> Result<Comment, DbcError> {
55-
let mut pairs = pair.into_inner();
83+
fn parse_signal_comment(mut pairs: Pairs<Rule>) -> Result<Comment, DbcError> {
5684
let message_id = next_rule(&mut pairs, Rule::message_id)?.try_into()?;
57-
let next_pair = next(&mut pairs)?;
58-
match next_pair.as_rule() {
59-
Rule::signal_name => {
60-
// This is a proper signal comment with signal name
61-
Ok(Comment::Signal {
62-
message_id,
63-
name: next_pair.as_str().to_string(),
64-
comment: inner_str(next_rule(&mut pairs, Rule::quoted_str)?),
65-
})
66-
}
67-
Rule::quoted_str => {
68-
// No signal name - treat as message comment
69-
Ok(Comment::Message {
70-
id: message_id,
71-
comment: inner_str(next_rule(&mut pairs, Rule::quoted_str)?),
72-
})
73-
}
74-
rule => Err(DbcError::UnknownRule(rule)),
75-
}
76-
}
77-
78-
/// Parse message comment: `BO_ <message_id> "comment"`
79-
fn parse_message_comment(pair: Pair<'_, Rule>) -> Result<Comment, DbcError> {
80-
let mut inner = pair.into_inner();
81-
let message_id = next_rule(&mut inner, Rule::message_id)?.try_into()?;
82-
let comment = inner_str(next_rule(&mut inner, Rule::quoted_str)?);
83-
84-
Ok(Comment::Message {
85-
id: message_id,
86-
comment,
87-
})
88-
}
89-
90-
/// Parse node comment: `BU_ <node_name> "comment"`
91-
fn parse_node_comment(pair: Pair<'_, Rule>) -> Result<Comment, DbcError> {
92-
let mut inner = pair.into_inner();
93-
let node_name = next_ident(&mut inner)?;
94-
let comment = inner_str(next_rule(&mut inner, Rule::quoted_str)?);
95-
96-
Ok(Comment::Node {
97-
name: node_name,
98-
comment,
99-
})
100-
}
101-
102-
/// Parse environment variable comment: `EV_ <env_var_name> "comment"`
103-
fn parse_env_var_comment(pair: Pair<'_, Rule>) -> Result<Comment, DbcError> {
104-
let mut inner = pair.into_inner();
105-
let env_var_name = next_ident(&mut inner)?;
106-
let comment = inner_str(next_rule(&mut inner, Rule::quoted_str)?);
107-
108-
Ok(Comment::EnvVar {
109-
name: env_var_name,
110-
comment,
111-
})
112-
}
113-
114-
/// Parse plain comment: `"comment"`
115-
fn parse_plain_comment(pair: Pair<'_, Rule>) -> Result<Comment, DbcError> {
116-
// comment_plain contains a quoted_str, so we need to get the inner pair
117-
let mut inner = pair.into_inner();
118-
let comment = inner_str(next_rule(&mut inner, Rule::quoted_str)?);
119-
Ok(Comment::Plain { comment })
120-
}
121-
122-
/// Helper to get next identifier string from pairs iterator
123-
fn next_ident<'a>(iter: &'a mut Pairs<Rule>) -> Result<String, DbcError> {
124-
let pair = next(iter)?;
125-
match pair.as_rule() {
126-
Rule::signal_name | Rule::node_name | Rule::env_var_name | Rule::ident => {
127-
Ok(pair.as_str().to_string())
128-
}
129-
rule => Err(DbcError::UnknownRule(rule)),
85+
if let Some(name) = next_optional_rule(&mut pairs, Rule::signal_name)? {
86+
// This is a proper signal comment with signal name
87+
Ok(Comment::Signal {
88+
message_id,
89+
name: name.as_str().to_string(),
90+
comment: inner_str(next_rule(&mut pairs, Rule::quoted_str)?),
91+
})
92+
} else {
93+
// No signal name - treat as message comment
94+
Ok(Comment::Message {
95+
id: message_id,
96+
comment: inner_str(next_rule(&mut pairs, Rule::quoted_str)?),
97+
})
13098
}
13199
}

src/ast/dbc.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,7 @@ pub(crate) fn dbc(buffer: &str) -> DbcResult<Dbc> {
253253
return Err(DbcError::SignalWithoutMessage);
254254
}
255255
}
256-
Rule::comment => {
257-
comments.push(pairs.try_into()?);
258-
}
256+
Rule::comment => comments.push(pairs.try_into()?),
259257
Rule::attr_def => attribute_definitions.push(pairs.try_into()?),
260258
Rule::attr_value => attribute_values.push(pairs.try_into()?),
261259
Rule::value_table => value_tables.push(pairs.try_into()?),

src/ast/message_transmitter.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ impl TryFrom<Pair<'_, Rule>> for MessageTransmitter {
1616

1717
fn try_from(value: Pair<'_, Rule>) -> Result<Self, Self::Error> {
1818
let mut pairs = validated_inner(value, Rule::message_transmitter)?;
19-
let message_id = next_rule(&mut pairs, Rule::message_id)?.try_into()?;
20-
let transmitter = collect_expected(&mut pairs, Rule::transmitter)?;
2119

2220
Ok(Self {
23-
message_id,
24-
transmitter,
21+
message_id: next_rule(&mut pairs, Rule::message_id)?.try_into()?,
22+
transmitter: collect_expected(&mut pairs, Rule::transmitter)?,
2523
})
2624
}
2725
}

src/ast/signal.rs

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use can_dbc_pest::{Pair, Rule};
22

33
use crate::ast::{ByteOrder, MultiplexIndicator, ValueType};
4-
use crate::parser::{inner_str, parse_float, parse_min_max_float, parse_uint, validated_inner};
4+
use crate::parser::{
5+
collect_strings, inner_str, next, next_optional_rule, next_rule, next_string, parse_float,
6+
parse_min_max_float, parse_uint, validated_inner,
7+
};
58
use crate::DbcError;
69

710
/// One or multiple signals are the payload of a CAN frame.
@@ -30,37 +33,24 @@ impl TryFrom<Pair<'_, Rule>> for Signal {
3033
type Error = DbcError;
3134

3235
fn try_from(value: Pair<'_, Rule>) -> Result<Self, Self::Error> {
33-
let pairs = validated_inner(value, Rule::signal)?;
36+
let mut pairs = validated_inner(value, Rule::signal)?;
3437

35-
let mut name = String::new();
36-
let mut multiplexer_indicator = MultiplexIndicator::Plain;
37-
let mut start_bit = 0u64;
38-
let mut size = 0u64;
39-
let mut byte_order = ByteOrder::BigEndian;
40-
let mut value_type = ValueType::Unsigned;
41-
let mut factor = 0.0f64;
42-
let mut offset = 0.0f64;
43-
let mut min = 0.0f64;
44-
let mut max = 0.0f64;
45-
let mut unit = String::new();
46-
let mut receivers = Vec::new();
47-
48-
for pair2 in pairs {
49-
match pair2.as_rule() {
50-
Rule::signal_name => name = pair2.as_str().to_string(),
51-
Rule::multiplexer_indicator => multiplexer_indicator = pair2.as_str().try_into()?,
52-
Rule::start_bit => start_bit = parse_uint(pair2)?,
53-
Rule::signal_size => size = parse_uint(pair2)?,
54-
Rule::big_endian | Rule::little_endian => byte_order = pair2.try_into()?,
55-
Rule::signed_type | Rule::unsigned_type => value_type = pair2.try_into()?,
56-
Rule::factor => factor = parse_float(pair2)?,
57-
Rule::offset => offset = parse_float(pair2)?,
58-
Rule::min_max => (min, max) = parse_min_max_float(pair2)?,
59-
Rule::unit => unit = inner_str(pair2),
60-
Rule::node_name => receivers.push(pair2.as_str().to_string()),
61-
v => return Err(DbcError::UnknownRule(v)),
62-
}
63-
}
38+
let name = next_string(&mut pairs, Rule::signal_name)?;
39+
let multiplexer_indicator =
40+
if let Some(v) = next_optional_rule(&mut pairs, Rule::multiplexer_indicator)? {
41+
v.as_str().try_into()?
42+
} else {
43+
MultiplexIndicator::Plain
44+
};
45+
let start_bit = parse_uint(next_rule(&mut pairs, Rule::start_bit)?)?;
46+
let size = parse_uint(next_rule(&mut pairs, Rule::signal_size)?)?;
47+
let byte_order = next(&mut pairs)?.try_into()?;
48+
let value_type = next(&mut pairs)?.try_into()?;
49+
let factor = parse_float(next_rule(&mut pairs, Rule::factor)?)?;
50+
let offset = parse_float(next_rule(&mut pairs, Rule::offset)?)?;
51+
let (min, max) = parse_min_max_float(next_rule(&mut pairs, Rule::min_max)?)?;
52+
let unit = inner_str(next_rule(&mut pairs, Rule::unit)?);
53+
let receivers = collect_strings(&mut pairs, Rule::node_name)?;
6454

6555
Ok(Self {
6656
name,

src/ast/signal_groups.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,14 @@ impl TryFrom<Pair<'_, Rule>> for SignalGroups {
2323
fn try_from(value: Pair<'_, Rule>) -> Result<Self, Self::Error> {
2424
let mut pairs = validated_inner(value, Rule::signal_group)?;
2525

26-
let message_id = next_rule(&mut pairs, Rule::message_id)?.try_into()?;
27-
let name = next_string(&mut pairs, Rule::group_name)?;
28-
let repetitions = parse_uint(next_rule(&mut pairs, Rule::multiplexer_id)?)?;
29-
let signal_names = collect_strings(&mut pairs, Rule::signal_name)?;
26+
let value = Self {
27+
message_id: next_rule(&mut pairs, Rule::message_id)?.try_into()?,
28+
name: next_string(&mut pairs, Rule::group_name)?,
29+
repetitions: parse_uint(next_rule(&mut pairs, Rule::multiplexer_id)?)?,
30+
signal_names: collect_strings(&mut pairs, Rule::signal_name)?,
31+
};
3032
expect_empty(&pairs)?;
3133

32-
Ok(Self {
33-
message_id,
34-
name,
35-
repetitions,
36-
signal_names,
37-
})
34+
Ok(value)
3835
}
3936
}

src/parser.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl From<PestError<Rule>> for DbcError {
5454

5555
/// Helper function to get the next pair and validate its rule
5656
pub(crate) fn next<'a>(iter: &'a mut Pairs<Rule>) -> DbcResult<Pair<'a, Rule>> {
57-
iter.next().ok_or(DbcError::NoMoreRules)
57+
iter.next().ok_or_else(|| DbcError::NoMoreRules)
5858
}
5959

6060
/// Helper function to get the next pair and validate its rule
@@ -92,7 +92,7 @@ pub(crate) fn next_string(iter: &mut Pairs<Rule>, expected: Rule) -> DbcResult<S
9292
/// Helper function to get a single pair and validate its rule
9393
pub(crate) fn single_inner(pair: Pair<Rule>, expected: Rule) -> DbcResult<Pair<Rule>> {
9494
let mut iter = pair.into_inner();
95-
let pair = iter.next().ok_or(DbcError::NoMoreRules)?;
95+
let pair = iter.next().ok_or_else(|| DbcError::NoMoreRules)?;
9696
if pair.as_rule() != expected {
9797
Err(DbcError::Expected(expected, pair.as_rule()))
9898
} else if let Some(next) = iter.next() {

0 commit comments

Comments
 (0)