Skip to content

Commit f0eca9a

Browse files
committed
refactor: enhance error handling, validation in parsing methods
1 parent dd51ef7 commit f0eca9a

28 files changed

+272
-231
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
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.0" }
27+
can-dbc-pest = { version = "0.5.1" }
2828
encoding_rs = { version = "0.8", optional = true }
2929
serde = { version = "1.0", features = ["derive"], optional = true }
3030
thiserror = "2.0.17"

src/ast/access_node.rs

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

3-
use crate::DbcError;
3+
use crate::parser::{validated, DbcError};
44

55
// TODO: consider merging with Transmitter
66

@@ -15,16 +15,11 @@ impl TryFrom<Pair<'_, Rule>> for AccessNode {
1515
type Error = DbcError;
1616

1717
fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
18-
match pair.as_rule() {
19-
Rule::node_name => {
20-
let name = pair.as_str();
21-
Ok(if name == "VECTOR__XXX" {
22-
Self::VectorXXX
23-
} else {
24-
Self::Name(name.to_string())
25-
})
26-
}
27-
_ => Err(Self::Error::ParseError),
28-
}
18+
let value = validated(pair, Rule::node_name)?.as_str();
19+
Ok(if value == "VECTOR__XXX" {
20+
Self::VectorXXX
21+
} else {
22+
Self::Name(value.to_string())
23+
})
2924
}
3025
}

src/ast/access_type.rs

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

3-
use crate::parser::{parse_uint, single_rule};
3+
use crate::parser::{parse_uint, single_inner, validated};
44
use crate::DbcError;
55

66
#[derive(Copy, Clone, Debug, PartialEq)]
@@ -16,18 +16,18 @@ impl TryFrom<Pair<'_, Rule>> for AccessType {
1616
type Error = DbcError;
1717

1818
fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
19-
match pair.as_rule() {
20-
Rule::access_type => {
21-
match parse_uint(single_rule(pair, Rule::uint)?)? {
22-
0 => Ok(Self::DummyNodeVector0),
23-
1 => Ok(Self::DummyNodeVector1),
24-
2 => Ok(Self::DummyNodeVector2),
25-
3 => Ok(Self::DummyNodeVector3),
26-
// FIXME: is this correct?
27-
_ => Ok(AccessType::DummyNodeVector0),
28-
}
29-
}
30-
_ => Err(Self::Error::ParseError),
31-
}
19+
let value = parse_uint(single_inner(
20+
validated(pair, Rule::access_type)?,
21+
Rule::uint,
22+
)?)?;
23+
24+
Ok(match value {
25+
0 => Self::DummyNodeVector0,
26+
1 => Self::DummyNodeVector1,
27+
2 => Self::DummyNodeVector2,
28+
3 => Self::DummyNodeVector3,
29+
// FIXME: is this correct?
30+
_ => AccessType::DummyNodeVector0,
31+
})
3232
}
3333
}

src/ast/attribute_default.rs

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

33
use crate::ast::AttributeValue;
4-
use crate::parser::{expect_empty, next_rule, parse_str, DbcError, DbcResult};
4+
use crate::parser::{expect_empty, inner_str, next, next_rule, DbcError};
55

66
#[derive(Clone, Debug, PartialEq)]
77
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -10,12 +10,13 @@ pub struct AttributeDefault {
1010
pub value: AttributeValue,
1111
}
1212

13-
impl AttributeDefault {
14-
/// Parse attribute default: `BA_DEF_DEF_ attribute_name default_value;`
15-
pub(crate) fn parse(pair: Pair<Rule>) -> DbcResult<Self> {
13+
impl TryFrom<Pair<'_, Rule>> for AttributeDefault {
14+
type Error = DbcError;
15+
16+
fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
1617
let mut pairs = pair.into_inner();
17-
let name = parse_str(next_rule(&mut pairs, Rule::attribute_name)?);
18-
let value = pairs.next().ok_or(DbcError::ParseError)?.try_into()?;
18+
let name = inner_str(next_rule(&mut pairs, Rule::attribute_name)?);
19+
let value = next(&mut pairs)?.try_into()?;
1920
expect_empty(&mut pairs)?;
2021

2122
Ok(Self { name, value })

src/ast/attribute_definition.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use can_dbc_pest::{Pair, Rule};
22

3-
use crate::parser::DbcResult;
3+
use crate::parser::DbcError;
44

55
#[derive(Clone, Debug, PartialEq)]
66
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -16,15 +16,21 @@ pub enum AttributeDefinition {
1616
Plain(String),
1717
}
1818

19-
impl AttributeDefinition {
19+
impl TryFrom<Pair<'_, Rule>> for AttributeDefinition {
20+
type Error = DbcError;
21+
2022
/// Parse attribute definition: `BA_DEF_ [object_type] attribute_name attribute_type [min max];`
21-
pub(crate) fn parse(pair: Pair<Rule>) -> DbcResult<Self> {
23+
fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
24+
let mut pairs = pair.into_inner();
2225
let mut definition_string = String::new();
2326
let mut object_type = "";
2427

25-
for pairs in pair.into_inner() {
26-
match pairs.as_rule() {
27-
Rule::object_type => object_type = pairs.as_str(),
28+
// Process all pairs
29+
while let Some(pair) = pairs.next() {
30+
match pair.as_rule() {
31+
Rule::object_type => {
32+
object_type = pair.as_str();
33+
}
2834
Rule::attribute_name
2935
| Rule::attribute_type_int
3036
| Rule::attribute_type_hex
@@ -34,9 +40,9 @@ impl AttributeDefinition {
3440
if !definition_string.is_empty() {
3541
definition_string.push(' ');
3642
}
37-
definition_string.push_str(pairs.as_str());
43+
definition_string.push_str(pair.as_str());
3844
}
39-
_ => panic!("Unexpected rule: {:?}", pairs.as_rule()),
45+
_ => return Err(DbcError::ParseError),
4046
}
4147
}
4248

src/ast/attribute_value.rs

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

3-
use crate::parser::{parse_float, parse_str};
4-
use crate::DbcError;
3+
use crate::parser::{inner_str, parse_float, DbcError};
54

65
#[derive(Clone, Debug, PartialEq)]
76
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
@@ -17,7 +16,7 @@ impl TryFrom<Pair<'_, Rule>> for AttributeValue {
1716

1817
fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
1918
match pair.as_rule() {
20-
Rule::quoted_str => Ok(Self::String(parse_str(pair))),
19+
Rule::quoted_str => Ok(Self::String(inner_str(pair))),
2120
Rule::number => Ok(Self::Double(parse_float(pair)?)),
2221
// FIXME: Add u64 and i64 parsing
2322
_ => Err(Self::Error::ParseError),

src/ast/attribute_value_for_object.rs

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

33
use crate::ast::AttributeValuedForObjectType;
44
use crate::parser::{
5-
expect_empty, next_rule, next_string, parse_float, parse_str, single_rule, DbcResult,
5+
expect_empty, inner_str, next_rule, next_string, parse_float, single_inner, DbcError,
66
};
77
use crate::{AttributeValue, MessageId};
88

@@ -13,9 +13,11 @@ pub struct AttributeValueForObject {
1313
pub value: AttributeValuedForObjectType,
1414
}
1515

16-
impl AttributeValueForObject {
16+
impl TryFrom<Pair<'_, Rule>> for AttributeValueForObject {
17+
type Error = DbcError;
18+
1719
/// Parse attribute value: `BA_ attribute_name [object_type] object_name value;`
18-
pub(crate) fn parse(pair: Pair<Rule>) -> DbcResult<Self> {
20+
fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
1921
let mut name = String::new();
2022
let mut object_type = None;
2123
let mut message_id: Option<MessageId> = None;
@@ -26,21 +28,21 @@ impl AttributeValueForObject {
2628

2729
for pairs in pair.into_inner() {
2830
match pairs.as_rule() {
29-
Rule::attribute_name => name = parse_str(pairs),
31+
Rule::attribute_name => name = inner_str(pairs),
3032
// num_str_value is a silent rule, so we get quoted_str or number directly
31-
Rule::quoted_str => value = Some(AttributeValue::String(parse_str(pairs))),
33+
Rule::quoted_str => value = Some(AttributeValue::String(inner_str(pairs))),
3234
Rule::number => value = Some(AttributeValue::Double(parse_float(pairs)?)),
3335
Rule::node_var => {
3436
object_type = Some(pairs.as_rule());
3537
// Parse the node name from the inner pairs
3638
// node_var contains: node_literal ~ node_name
3739
// node_literal is silent (_), so we get node_name directly
38-
node_name = Some(single_rule(pairs, Rule::node_name)?.as_str().to_string());
40+
node_name = Some(single_inner(pairs, Rule::node_name)?.as_str().to_string());
3941
}
4042
Rule::msg_var => {
4143
object_type = Some(pairs.as_rule());
4244
// Parse the message ID from the inner pairs
43-
message_id = Some(single_rule(pairs, Rule::message_id)?.try_into()?);
45+
message_id = Some(single_inner(pairs, Rule::message_id)?.try_into()?);
4446
}
4547
Rule::signal_var => {
4648
object_type = Some(pairs.as_rule());
@@ -55,7 +57,7 @@ impl AttributeValueForObject {
5557
// Parse the environment variable name from the inner pairs
5658
// env_var contains: env_literal ~ env_var_name
5759
// env_literal is silent (_), so we get env_var_name directly
58-
let v = single_rule(pairs, Rule::env_var_name)?;
60+
let v = single_inner(pairs, Rule::env_var_name)?;
5961
env_var_name = Some(v.as_str().to_string());
6062
}
6163
other => panic!("What is this? {other:?}"),

src/ast/baudrate.rs

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

3-
use crate::parser::DbcResult;
3+
use crate::parser::DbcError;
44

55
/// Baudrate of network in KBit/s
66
#[derive(Copy, Clone, Debug, PartialEq)]
77
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
88
pub struct Baudrate(pub u64);
99

10-
impl Baudrate {
10+
impl TryFrom<Pair<'_, Rule>> for Baudrate {
11+
type Error = DbcError;
12+
1113
/// Parse bit timing: `BS_: [baud_rate : BTR1 , BTR2 ]`
12-
pub(crate) fn parse(pair: Pair<Rule>) -> DbcResult<Vec<Self>> {
13-
let pairs = pair.into_inner();
14-
if pairs.len() == 0 {
15-
return Ok(vec![]);
16-
}
14+
fn try_from(_pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
1715
todo!("Bit timing parsing not implemented yet");
1816
}
1917
}

src/ast/comment.rs

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

33
use crate::ast::MessageId;
4-
use crate::parser::{parse_str, parse_uint, single_rule, DbcResult};
4+
use crate::parser::{inner_str, parse_uint, single_inner, DbcError};
55

66
/// Object comments
77
#[derive(Clone, Debug, PartialEq)]
@@ -29,9 +29,11 @@ pub enum Comment {
2929
},
3030
}
3131

32-
impl Comment {
32+
impl TryFrom<Pair<'_, Rule>> for Comment {
33+
type Error = DbcError;
34+
3335
/// Parse comment: `CM_ [BU_|BO_|SG_|EV_] object_name "comment_text";`
34-
pub(crate) fn parse(pair: Pair<Rule>) -> DbcResult<Option<Self>> {
36+
fn try_from(pair: Pair<'_, Rule>) -> Result<Self, Self::Error> {
3537
let mut comment = String::new();
3638
let mut message_id = None;
3739
let mut signal_name = None;
@@ -40,16 +42,19 @@ impl Comment {
4042

4143
for pairs in pair.into_inner() {
4244
match pairs.as_rule() {
43-
Rule::quoted_str => comment = parse_str(pairs),
45+
Rule::quoted_str => comment = inner_str(pairs),
4446
Rule::msg_var => {
45-
message_id = Some(parse_uint(single_rule(pairs, Rule::message_id)?)? as u32);
47+
message_id = Some(parse_uint(single_inner(pairs, Rule::message_id)?)? as u32);
4648
}
4749
Rule::node_var => {
48-
node_name = Some(single_rule(pairs, Rule::node_name)?.as_str().to_string());
50+
node_name = Some(single_inner(pairs, Rule::node_name)?.as_str().to_string());
4951
}
5052
Rule::env_var => {
51-
env_var_name =
52-
Some(single_rule(pairs, Rule::env_var_name)?.as_str().to_string());
53+
env_var_name = Some(
54+
single_inner(pairs, Rule::env_var_name)?
55+
.as_str()
56+
.to_string(),
57+
);
5358
}
5459
Rule::signal_var => {
5560
for sub_pair in pairs.into_inner() {
@@ -85,16 +90,16 @@ impl Comment {
8590
});
8691

8792
Ok(match (message_id, signal_name, node_name, env_var_name) {
88-
(Some(message_id), Some(name), _, _) => Some(Self::Signal {
93+
(Some(message_id), Some(name), _, _) => Self::Signal {
8994
message_id,
9095
name,
9196
comment,
92-
}),
93-
(Some(id), None, _, _) => Some(Self::Message { id, comment }),
94-
(_, _, Some(name), _) => Some(Self::Node { name, comment }),
95-
(_, _, _, Some(name)) => Some(Self::EnvVar { name, comment }),
96-
_ if !comment.is_empty() => Some(Self::Plain { comment }),
97-
_ => None,
97+
},
98+
(Some(id), None, _, _) => Self::Message { id, comment },
99+
(_, _, Some(name), _) => Self::Node { name, comment },
100+
(_, _, _, Some(name)) => Self::EnvVar { name, comment },
101+
_ if !comment.is_empty() => Self::Plain { comment },
102+
_ => return Err(DbcError::ParseError),
98103
})
99104
}
100105
}

0 commit comments

Comments
 (0)