Dbc

Struct Dbc 

Source
pub struct Dbc { /* private fields */ }
Expand description

Represents a complete DBC (CAN Database) file.

A Dbc contains all the information from a DBC file: version information, node definitions, and CAN messages with their signals.

§Examples

use dbc_rs::Dbc;

let content = "VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM";
let dbc = Dbc::parse(content)?;

Implementations§

Source§

impl Dbc

Source

pub fn builder() -> DbcBuilder

Create a new builder for constructing a Dbc

§Examples
use dbc_rs::{Dbc, Version, Nodes, Message, Signal, ByteOrder, Receivers};

let version = Version::builder().major(1).minor(0).build()?;
let nodes = Nodes::builder().add_node("ECM").add_node("TCM").build()?;

let signal = Signal::builder()
    .name("RPM")
    .start_bit(0)
    .length(16)
    .byte_order(ByteOrder::BigEndian)
    .unsigned(true)
    .factor(0.25)
    .offset(0.0)
    .min(0.0)
    .max(8000.0)
    .unit("rpm")
    .receivers(Receivers::Broadcast)
    .build()?;

let message = Message::builder()
    .id(256)
    .name("EngineData")
    .dlc(8)
    .sender("ECM")
    .add_signal(signal)
    .build()?;

let dbc = Dbc::builder()
    .version(version)
    .nodes(nodes)
    .add_message(message)
    .build()?;
§See Also
Examples found in repository?
examples/create_dbc.rs (line 74)
3fn main() -> Result<(), dbc_rs::Error> {
4    // Create version "1.0" using builder
5    let version = Version::builder().major(1).minor(0).build()?;
6
7    // Create nodes: ECM and TCM using builder
8    let nodes = Nodes::builder().add_node("ECM").add_node("TCM").build()?;
9
10    // Create signals for Engine message using the builder pattern
11    let rpm_signal = Signal::builder()
12        .name("RPM")
13        .start_bit(0)
14        .length(16)
15        .byte_order(ByteOrder::LittleEndian)
16        .unsigned(true)
17        .factor(0.25)
18        .offset(0.0)
19        .min(0.0)
20        .max(8000.0)
21        .unit("rpm")
22        .receivers(Receivers::None)
23        .build()?;
24
25    let temp_signal = Signal::builder()
26        .name("Temp")
27        .start_bit(16)
28        .length(8)
29        .byte_order(ByteOrder::LittleEndian)
30        .unsigned(false)
31        .factor(1.0)
32        .offset(-40.0)
33        .min(-40.0)
34        .max(215.0)
35        .unit("°C")
36        .receivers(Receivers::None)
37        .build()?;
38
39    // Create signals for Brake message
40    let pressure_signal = Signal::builder()
41        .name("Pressure")
42        .start_bit(0)
43        .length(16)
44        .byte_order(ByteOrder::BigEndian)
45        .unsigned(true)
46        .factor(0.1)
47        .offset(0.0)
48        .min(0.0)
49        .max(1000.0)
50        .unit("bar")
51        .receivers(Receivers::None)
52        .build()?;
53
54    // Create Engine message (ID 256, DLC 8, sender ECM) using the builder pattern
55    let engine_message = Message::builder()
56        .id(256)
57        .name("Engine")
58        .dlc(8)
59        .sender("ECM")
60        .add_signal(rpm_signal)
61        .add_signal(temp_signal)
62        .build()?;
63
64    // Create Brake message (ID 512, DLC 4, sender TCM) using the builder pattern
65    let brake_message = Message::builder()
66        .id(512)
67        .name("Brake")
68        .dlc(4)
69        .sender("TCM")
70        .add_signal(pressure_signal)
71        .build()?;
72
73    // Create DBC with all components using the builder pattern
74    let dbc = Dbc::builder()
75        .version(version)
76        .nodes(nodes)
77        .add_message(engine_message)
78        .add_message(brake_message)
79        .build()?;
80
81    // Verify the created DBC
82    println!("Created DBC with version: {}", dbc.version().to_string());
83    println!("Nodes: {}", dbc.nodes().to_string());
84    println!("Messages: {}", dbc.messages().len());
85
86    for msg in dbc.messages() {
87        println!(
88            "  Message {} (ID: {}, DLC: {}, Sender: {})",
89            msg.name(),
90            msg.id(),
91            msg.dlc(),
92            msg.sender()
93        );
94        for sig in msg.signals() {
95            println!(
96                "    Signal {}: {}|{}@{} (factor: {}, offset: {}) [{:.1}|{:.1}] \"{}\"",
97                sig.name(),
98                sig.start_bit(),
99                sig.length(),
100                if sig.byte_order() == ByteOrder::LittleEndian {
101                    "0"
102                } else {
103                    "1"
104                },
105                sig.factor(),
106                sig.offset(),
107                sig.min(),
108                sig.max(),
109                sig.unit().unwrap_or("")
110            );
111        }
112    }
113
114    // The DBC object is now ready to use
115    // You can access messages, signals, and other data through the getter methods
116
117    Ok(())
118}
Source

pub fn version(&self) -> &Version

Get the version information

Examples found in repository?
examples/create_dbc.rs (line 82)
3fn main() -> Result<(), dbc_rs::Error> {
4    // Create version "1.0" using builder
5    let version = Version::builder().major(1).minor(0).build()?;
6
7    // Create nodes: ECM and TCM using builder
8    let nodes = Nodes::builder().add_node("ECM").add_node("TCM").build()?;
9
10    // Create signals for Engine message using the builder pattern
11    let rpm_signal = Signal::builder()
12        .name("RPM")
13        .start_bit(0)
14        .length(16)
15        .byte_order(ByteOrder::LittleEndian)
16        .unsigned(true)
17        .factor(0.25)
18        .offset(0.0)
19        .min(0.0)
20        .max(8000.0)
21        .unit("rpm")
22        .receivers(Receivers::None)
23        .build()?;
24
25    let temp_signal = Signal::builder()
26        .name("Temp")
27        .start_bit(16)
28        .length(8)
29        .byte_order(ByteOrder::LittleEndian)
30        .unsigned(false)
31        .factor(1.0)
32        .offset(-40.0)
33        .min(-40.0)
34        .max(215.0)
35        .unit("°C")
36        .receivers(Receivers::None)
37        .build()?;
38
39    // Create signals for Brake message
40    let pressure_signal = Signal::builder()
41        .name("Pressure")
42        .start_bit(0)
43        .length(16)
44        .byte_order(ByteOrder::BigEndian)
45        .unsigned(true)
46        .factor(0.1)
47        .offset(0.0)
48        .min(0.0)
49        .max(1000.0)
50        .unit("bar")
51        .receivers(Receivers::None)
52        .build()?;
53
54    // Create Engine message (ID 256, DLC 8, sender ECM) using the builder pattern
55    let engine_message = Message::builder()
56        .id(256)
57        .name("Engine")
58        .dlc(8)
59        .sender("ECM")
60        .add_signal(rpm_signal)
61        .add_signal(temp_signal)
62        .build()?;
63
64    // Create Brake message (ID 512, DLC 4, sender TCM) using the builder pattern
65    let brake_message = Message::builder()
66        .id(512)
67        .name("Brake")
68        .dlc(4)
69        .sender("TCM")
70        .add_signal(pressure_signal)
71        .build()?;
72
73    // Create DBC with all components using the builder pattern
74    let dbc = Dbc::builder()
75        .version(version)
76        .nodes(nodes)
77        .add_message(engine_message)
78        .add_message(brake_message)
79        .build()?;
80
81    // Verify the created DBC
82    println!("Created DBC with version: {}", dbc.version().to_string());
83    println!("Nodes: {}", dbc.nodes().to_string());
84    println!("Messages: {}", dbc.messages().len());
85
86    for msg in dbc.messages() {
87        println!(
88            "  Message {} (ID: {}, DLC: {}, Sender: {})",
89            msg.name(),
90            msg.id(),
91            msg.dlc(),
92            msg.sender()
93        );
94        for sig in msg.signals() {
95            println!(
96                "    Signal {}: {}|{}@{} (factor: {}, offset: {}) [{:.1}|{:.1}] \"{}\"",
97                sig.name(),
98                sig.start_bit(),
99                sig.length(),
100                if sig.byte_order() == ByteOrder::LittleEndian {
101                    "0"
102                } else {
103                    "1"
104                },
105                sig.factor(),
106                sig.offset(),
107                sig.min(),
108                sig.max(),
109                sig.unit().unwrap_or("")
110            );
111        }
112    }
113
114    // The DBC object is now ready to use
115    // You can access messages, signals, and other data through the getter methods
116
117    Ok(())
118}
Source

pub fn nodes(&self) -> &Nodes

Get the nodes information

Examples found in repository?
examples/create_dbc.rs (line 83)
3fn main() -> Result<(), dbc_rs::Error> {
4    // Create version "1.0" using builder
5    let version = Version::builder().major(1).minor(0).build()?;
6
7    // Create nodes: ECM and TCM using builder
8    let nodes = Nodes::builder().add_node("ECM").add_node("TCM").build()?;
9
10    // Create signals for Engine message using the builder pattern
11    let rpm_signal = Signal::builder()
12        .name("RPM")
13        .start_bit(0)
14        .length(16)
15        .byte_order(ByteOrder::LittleEndian)
16        .unsigned(true)
17        .factor(0.25)
18        .offset(0.0)
19        .min(0.0)
20        .max(8000.0)
21        .unit("rpm")
22        .receivers(Receivers::None)
23        .build()?;
24
25    let temp_signal = Signal::builder()
26        .name("Temp")
27        .start_bit(16)
28        .length(8)
29        .byte_order(ByteOrder::LittleEndian)
30        .unsigned(false)
31        .factor(1.0)
32        .offset(-40.0)
33        .min(-40.0)
34        .max(215.0)
35        .unit("°C")
36        .receivers(Receivers::None)
37        .build()?;
38
39    // Create signals for Brake message
40    let pressure_signal = Signal::builder()
41        .name("Pressure")
42        .start_bit(0)
43        .length(16)
44        .byte_order(ByteOrder::BigEndian)
45        .unsigned(true)
46        .factor(0.1)
47        .offset(0.0)
48        .min(0.0)
49        .max(1000.0)
50        .unit("bar")
51        .receivers(Receivers::None)
52        .build()?;
53
54    // Create Engine message (ID 256, DLC 8, sender ECM) using the builder pattern
55    let engine_message = Message::builder()
56        .id(256)
57        .name("Engine")
58        .dlc(8)
59        .sender("ECM")
60        .add_signal(rpm_signal)
61        .add_signal(temp_signal)
62        .build()?;
63
64    // Create Brake message (ID 512, DLC 4, sender TCM) using the builder pattern
65    let brake_message = Message::builder()
66        .id(512)
67        .name("Brake")
68        .dlc(4)
69        .sender("TCM")
70        .add_signal(pressure_signal)
71        .build()?;
72
73    // Create DBC with all components using the builder pattern
74    let dbc = Dbc::builder()
75        .version(version)
76        .nodes(nodes)
77        .add_message(engine_message)
78        .add_message(brake_message)
79        .build()?;
80
81    // Verify the created DBC
82    println!("Created DBC with version: {}", dbc.version().to_string());
83    println!("Nodes: {}", dbc.nodes().to_string());
84    println!("Messages: {}", dbc.messages().len());
85
86    for msg in dbc.messages() {
87        println!(
88            "  Message {} (ID: {}, DLC: {}, Sender: {})",
89            msg.name(),
90            msg.id(),
91            msg.dlc(),
92            msg.sender()
93        );
94        for sig in msg.signals() {
95            println!(
96                "    Signal {}: {}|{}@{} (factor: {}, offset: {}) [{:.1}|{:.1}] \"{}\"",
97                sig.name(),
98                sig.start_bit(),
99                sig.length(),
100                if sig.byte_order() == ByteOrder::LittleEndian {
101                    "0"
102                } else {
103                    "1"
104                },
105                sig.factor(),
106                sig.offset(),
107                sig.min(),
108                sig.max(),
109                sig.unit().unwrap_or("")
110            );
111        }
112    }
113
114    // The DBC object is now ready to use
115    // You can access messages, signals, and other data through the getter methods
116
117    Ok(())
118}
Source

pub fn messages(&self) -> &[Message]

Get a read-only slice of messages

Examples found in repository?
examples/read_from_sources.rs (line 20)
4fn main() -> Result<(), dbc_rs::Error> {
5    let dbc_content = r#"VERSION "1.0"
6
7BU_: ECM TCM
8
9BO_ 256 Engine : 8 ECM
10 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm"
11 SG_ Temp : 16|8@1- (1,-40) [-40|215] "°C"
12
13BO_ 512 Brake : 4 TCM
14 SG_ Pressure : 0|16@1+ (0.1,0) [0|1000] "bar"
15"#;
16
17    // Method 1: Parse from string slice (works in no_std)
18    println!("1. Parsing from &str:");
19    let dbc1 = Dbc::parse(dbc_content)?;
20    println!("   Parsed {} messages", dbc1.messages().len());
21
22    // Method 2: Parse from bytes (works in no_std)
23    println!("2. Parsing from &[u8]:");
24    let bytes = dbc_content.as_bytes();
25    let dbc2 = Dbc::parse_bytes(bytes)?;
26    println!("   Parsed {} messages", dbc2.messages().len());
27
28    // Method 3: Parse from String (works in no_std)
29    println!("3. Parsing from String:");
30    let string = String::from(dbc_content);
31    let dbc3 = Dbc::parse_from(string)?;
32    println!("   Parsed {} messages", dbc3.messages().len());
33
34    // Method 4: Parse from std::io::Read (requires std feature)
35    #[cfg(feature = "std")]
36    {
37        println!("4. Parsing from std::io::Read (Cursor):");
38        let cursor = Cursor::new(dbc_content.as_bytes());
39        let dbc4 = Dbc::from_reader(cursor)?;
40        println!("   Parsed {} messages", dbc4.messages().len());
41
42        // Method 5: Parse from File (requires std feature)
43        println!("5. Parsing from File:");
44        if let Ok(file) = std::fs::File::open("tests/data/simple.dbc") {
45            let dbc5 = Dbc::from_reader(file)?;
46            println!("   Parsed {} messages from file", dbc5.messages().len());
47        } else {
48            println!("   File not found (this is OK for the example)");
49        }
50    }
51
52    Ok(())
53}
More examples
Hide additional examples
examples/create_dbc.rs (line 84)
3fn main() -> Result<(), dbc_rs::Error> {
4    // Create version "1.0" using builder
5    let version = Version::builder().major(1).minor(0).build()?;
6
7    // Create nodes: ECM and TCM using builder
8    let nodes = Nodes::builder().add_node("ECM").add_node("TCM").build()?;
9
10    // Create signals for Engine message using the builder pattern
11    let rpm_signal = Signal::builder()
12        .name("RPM")
13        .start_bit(0)
14        .length(16)
15        .byte_order(ByteOrder::LittleEndian)
16        .unsigned(true)
17        .factor(0.25)
18        .offset(0.0)
19        .min(0.0)
20        .max(8000.0)
21        .unit("rpm")
22        .receivers(Receivers::None)
23        .build()?;
24
25    let temp_signal = Signal::builder()
26        .name("Temp")
27        .start_bit(16)
28        .length(8)
29        .byte_order(ByteOrder::LittleEndian)
30        .unsigned(false)
31        .factor(1.0)
32        .offset(-40.0)
33        .min(-40.0)
34        .max(215.0)
35        .unit("°C")
36        .receivers(Receivers::None)
37        .build()?;
38
39    // Create signals for Brake message
40    let pressure_signal = Signal::builder()
41        .name("Pressure")
42        .start_bit(0)
43        .length(16)
44        .byte_order(ByteOrder::BigEndian)
45        .unsigned(true)
46        .factor(0.1)
47        .offset(0.0)
48        .min(0.0)
49        .max(1000.0)
50        .unit("bar")
51        .receivers(Receivers::None)
52        .build()?;
53
54    // Create Engine message (ID 256, DLC 8, sender ECM) using the builder pattern
55    let engine_message = Message::builder()
56        .id(256)
57        .name("Engine")
58        .dlc(8)
59        .sender("ECM")
60        .add_signal(rpm_signal)
61        .add_signal(temp_signal)
62        .build()?;
63
64    // Create Brake message (ID 512, DLC 4, sender TCM) using the builder pattern
65    let brake_message = Message::builder()
66        .id(512)
67        .name("Brake")
68        .dlc(4)
69        .sender("TCM")
70        .add_signal(pressure_signal)
71        .build()?;
72
73    // Create DBC with all components using the builder pattern
74    let dbc = Dbc::builder()
75        .version(version)
76        .nodes(nodes)
77        .add_message(engine_message)
78        .add_message(brake_message)
79        .build()?;
80
81    // Verify the created DBC
82    println!("Created DBC with version: {}", dbc.version().to_string());
83    println!("Nodes: {}", dbc.nodes().to_string());
84    println!("Messages: {}", dbc.messages().len());
85
86    for msg in dbc.messages() {
87        println!(
88            "  Message {} (ID: {}, DLC: {}, Sender: {})",
89            msg.name(),
90            msg.id(),
91            msg.dlc(),
92            msg.sender()
93        );
94        for sig in msg.signals() {
95            println!(
96                "    Signal {}: {}|{}@{} (factor: {}, offset: {}) [{:.1}|{:.1}] \"{}\"",
97                sig.name(),
98                sig.start_bit(),
99                sig.length(),
100                if sig.byte_order() == ByteOrder::LittleEndian {
101                    "0"
102                } else {
103                    "1"
104                },
105                sig.factor(),
106                sig.offset(),
107                sig.min(),
108                sig.max(),
109                sig.unit().unwrap_or("")
110            );
111        }
112    }
113
114    // The DBC object is now ready to use
115    // You can access messages, signals, and other data through the getter methods
116
117    Ok(())
118}
Source

pub fn parse(data: &str) -> Result<Self, Error>

Parse a DBC file from a string slice

This is the core parsing method that works in both std and no_std environments.

§Errors

Returns an error if:

  • The file is empty
  • The version line is missing or invalid
  • Nodes are not defined
  • Any message or signal fails to parse
  • Validation fails (duplicate IDs, invalid senders, etc.)
§Examples
use dbc_rs::Dbc;

let content = "VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM\n SG_ RPM : 0|16@1+ (0.25,0) [0|8000] \"rpm\"";
let dbc = Dbc::parse(content)?;
§See Also
Examples found in repository?
examples/read_from_sources.rs (line 19)
4fn main() -> Result<(), dbc_rs::Error> {
5    let dbc_content = r#"VERSION "1.0"
6
7BU_: ECM TCM
8
9BO_ 256 Engine : 8 ECM
10 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm"
11 SG_ Temp : 16|8@1- (1,-40) [-40|215] "°C"
12
13BO_ 512 Brake : 4 TCM
14 SG_ Pressure : 0|16@1+ (0.1,0) [0|1000] "bar"
15"#;
16
17    // Method 1: Parse from string slice (works in no_std)
18    println!("1. Parsing from &str:");
19    let dbc1 = Dbc::parse(dbc_content)?;
20    println!("   Parsed {} messages", dbc1.messages().len());
21
22    // Method 2: Parse from bytes (works in no_std)
23    println!("2. Parsing from &[u8]:");
24    let bytes = dbc_content.as_bytes();
25    let dbc2 = Dbc::parse_bytes(bytes)?;
26    println!("   Parsed {} messages", dbc2.messages().len());
27
28    // Method 3: Parse from String (works in no_std)
29    println!("3. Parsing from String:");
30    let string = String::from(dbc_content);
31    let dbc3 = Dbc::parse_from(string)?;
32    println!("   Parsed {} messages", dbc3.messages().len());
33
34    // Method 4: Parse from std::io::Read (requires std feature)
35    #[cfg(feature = "std")]
36    {
37        println!("4. Parsing from std::io::Read (Cursor):");
38        let cursor = Cursor::new(dbc_content.as_bytes());
39        let dbc4 = Dbc::from_reader(cursor)?;
40        println!("   Parsed {} messages", dbc4.messages().len());
41
42        // Method 5: Parse from File (requires std feature)
43        println!("5. Parsing from File:");
44        if let Ok(file) = std::fs::File::open("tests/data/simple.dbc") {
45            let dbc5 = Dbc::from_reader(file)?;
46            println!("   Parsed {} messages from file", dbc5.messages().len());
47        } else {
48            println!("   File not found (this is OK for the example)");
49        }
50    }
51
52    Ok(())
53}
Source

pub fn parse_bytes(data: &[u8]) -> Result<Self, Error>

Parse a DBC file from a byte slice

This method accepts &[u8] and converts it to a string for parsing. Works in both std and no_std environments.

§Errors

Returns an error if the bytes are not valid UTF-8.

§Examples
use dbc_rs::Dbc;

let bytes = b"VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM\n SG_ RPM : 0|16@1+ (0.25,0) [0|8000] \"rpm\"";
let dbc = Dbc::parse_bytes(bytes)?;
Examples found in repository?
examples/read_from_sources.rs (line 25)
4fn main() -> Result<(), dbc_rs::Error> {
5    let dbc_content = r#"VERSION "1.0"
6
7BU_: ECM TCM
8
9BO_ 256 Engine : 8 ECM
10 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm"
11 SG_ Temp : 16|8@1- (1,-40) [-40|215] "°C"
12
13BO_ 512 Brake : 4 TCM
14 SG_ Pressure : 0|16@1+ (0.1,0) [0|1000] "bar"
15"#;
16
17    // Method 1: Parse from string slice (works in no_std)
18    println!("1. Parsing from &str:");
19    let dbc1 = Dbc::parse(dbc_content)?;
20    println!("   Parsed {} messages", dbc1.messages().len());
21
22    // Method 2: Parse from bytes (works in no_std)
23    println!("2. Parsing from &[u8]:");
24    let bytes = dbc_content.as_bytes();
25    let dbc2 = Dbc::parse_bytes(bytes)?;
26    println!("   Parsed {} messages", dbc2.messages().len());
27
28    // Method 3: Parse from String (works in no_std)
29    println!("3. Parsing from String:");
30    let string = String::from(dbc_content);
31    let dbc3 = Dbc::parse_from(string)?;
32    println!("   Parsed {} messages", dbc3.messages().len());
33
34    // Method 4: Parse from std::io::Read (requires std feature)
35    #[cfg(feature = "std")]
36    {
37        println!("4. Parsing from std::io::Read (Cursor):");
38        let cursor = Cursor::new(dbc_content.as_bytes());
39        let dbc4 = Dbc::from_reader(cursor)?;
40        println!("   Parsed {} messages", dbc4.messages().len());
41
42        // Method 5: Parse from File (requires std feature)
43        println!("5. Parsing from File:");
44        if let Ok(file) = std::fs::File::open("tests/data/simple.dbc") {
45            let dbc5 = Dbc::from_reader(file)?;
46            println!("   Parsed {} messages from file", dbc5.messages().len());
47        } else {
48            println!("   File not found (this is OK for the example)");
49        }
50    }
51
52    Ok(())
53}
Source

pub fn parse_from<S: AsRef<str>>(data: S) -> Result<Self, Error>

Parse a DBC file from any type that can be converted to a string slice

This is a convenience method that works with String, &str, Box<str>, etc. Works in both std and no_std environments.

§Examples
use dbc_rs::Dbc;

let content = String::from("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM\n SG_ RPM : 0|16@1+ (0.25,0) [0|8000] \"rpm\"");
let dbc = Dbc::parse_from(content)?;
§See Also
Examples found in repository?
examples/read_from_sources.rs (line 31)
4fn main() -> Result<(), dbc_rs::Error> {
5    let dbc_content = r#"VERSION "1.0"
6
7BU_: ECM TCM
8
9BO_ 256 Engine : 8 ECM
10 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm"
11 SG_ Temp : 16|8@1- (1,-40) [-40|215] "°C"
12
13BO_ 512 Brake : 4 TCM
14 SG_ Pressure : 0|16@1+ (0.1,0) [0|1000] "bar"
15"#;
16
17    // Method 1: Parse from string slice (works in no_std)
18    println!("1. Parsing from &str:");
19    let dbc1 = Dbc::parse(dbc_content)?;
20    println!("   Parsed {} messages", dbc1.messages().len());
21
22    // Method 2: Parse from bytes (works in no_std)
23    println!("2. Parsing from &[u8]:");
24    let bytes = dbc_content.as_bytes();
25    let dbc2 = Dbc::parse_bytes(bytes)?;
26    println!("   Parsed {} messages", dbc2.messages().len());
27
28    // Method 3: Parse from String (works in no_std)
29    println!("3. Parsing from String:");
30    let string = String::from(dbc_content);
31    let dbc3 = Dbc::parse_from(string)?;
32    println!("   Parsed {} messages", dbc3.messages().len());
33
34    // Method 4: Parse from std::io::Read (requires std feature)
35    #[cfg(feature = "std")]
36    {
37        println!("4. Parsing from std::io::Read (Cursor):");
38        let cursor = Cursor::new(dbc_content.as_bytes());
39        let dbc4 = Dbc::from_reader(cursor)?;
40        println!("   Parsed {} messages", dbc4.messages().len());
41
42        // Method 5: Parse from File (requires std feature)
43        println!("5. Parsing from File:");
44        if let Ok(file) = std::fs::File::open("tests/data/simple.dbc") {
45            let dbc5 = Dbc::from_reader(file)?;
46            println!("   Parsed {} messages from file", dbc5.messages().len());
47        } else {
48            println!("   File not found (this is OK for the example)");
49        }
50    }
51
52    Ok(())
53}
Source

pub fn save(&self) -> String

Serialize the DBC structure back to DBC file format

This method converts a Dbc instance back into a string representation that matches the DBC file format. It uses the to_dbc_string() methods of the individual components (Version, Nodes, Message, Signal) to compose the complete DBC file.

Works in both std and no_std environments.

§Examples
use dbc_rs::Dbc;

let content = "VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM\n SG_ RPM : 0|16@1+ (0.25,0) [0|8000] \"rpm\"";
let dbc = Dbc::parse(content)?;
let saved = dbc.save();
// The saved content should be equivalent to the original
§See Also
Source§

impl Dbc

Source

pub fn from_reader<R: Read>(reader: R) -> Result<Self, Error>

Parse a DBC file from any type implementing std::io::Read

This method reads from files, network streams, in-memory buffers, or any other source that implements std::io::Read. Only available when the std feature is enabled.

§Errors

Returns an error if:

  • Reading from the source fails
  • The data is not valid UTF-8
  • The DBC file format is invalid
§Examples
use dbc_rs::Dbc;
use std::fs::File;

let file = File::open("example.dbc").expect("file not found");
let dbc = Dbc::from_reader(file).expect("failed to parse");

Reading from a buffer:

use dbc_rs::Dbc;
use std::io::Cursor;

let data = b"VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM\n SG_ RPM : 0|16@1+ (0.25,0) [0|8000] \"rpm\"";
let cursor = Cursor::new(data);
let dbc = Dbc::from_reader(cursor)?;
§See Also
  • parse - Parse from string slice (works in no_std)
  • parse_bytes - Parse from bytes (works in no_std)
  • parse_from - Parse from owned string types (works in no_std)
Examples found in repository?
examples/read_from_sources.rs (line 39)
4fn main() -> Result<(), dbc_rs::Error> {
5    let dbc_content = r#"VERSION "1.0"
6
7BU_: ECM TCM
8
9BO_ 256 Engine : 8 ECM
10 SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm"
11 SG_ Temp : 16|8@1- (1,-40) [-40|215] "°C"
12
13BO_ 512 Brake : 4 TCM
14 SG_ Pressure : 0|16@1+ (0.1,0) [0|1000] "bar"
15"#;
16
17    // Method 1: Parse from string slice (works in no_std)
18    println!("1. Parsing from &str:");
19    let dbc1 = Dbc::parse(dbc_content)?;
20    println!("   Parsed {} messages", dbc1.messages().len());
21
22    // Method 2: Parse from bytes (works in no_std)
23    println!("2. Parsing from &[u8]:");
24    let bytes = dbc_content.as_bytes();
25    let dbc2 = Dbc::parse_bytes(bytes)?;
26    println!("   Parsed {} messages", dbc2.messages().len());
27
28    // Method 3: Parse from String (works in no_std)
29    println!("3. Parsing from String:");
30    let string = String::from(dbc_content);
31    let dbc3 = Dbc::parse_from(string)?;
32    println!("   Parsed {} messages", dbc3.messages().len());
33
34    // Method 4: Parse from std::io::Read (requires std feature)
35    #[cfg(feature = "std")]
36    {
37        println!("4. Parsing from std::io::Read (Cursor):");
38        let cursor = Cursor::new(dbc_content.as_bytes());
39        let dbc4 = Dbc::from_reader(cursor)?;
40        println!("   Parsed {} messages", dbc4.messages().len());
41
42        // Method 5: Parse from File (requires std feature)
43        println!("5. Parsing from File:");
44        if let Ok(file) = std::fs::File::open("tests/data/simple.dbc") {
45            let dbc5 = Dbc::from_reader(file)?;
46            println!("   Parsed {} messages from file", dbc5.messages().len());
47        } else {
48            println!("   File not found (this is OK for the example)");
49        }
50    }
51
52    Ok(())
53}

Trait Implementations§

Source§

impl Debug for Dbc

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Dbc

§

impl RefUnwindSafe for Dbc

§

impl Send for Dbc

§

impl Sync for Dbc

§

impl Unpin for Dbc

§

impl UnwindSafe for Dbc

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.