pub struct Dbc { /* private fields */ }Expand description
Represents a complete DBC (CAN database) file.
A Dbc contains:
- An optional version string
- A list of nodes (ECUs)
- A collection of messages with their signals
§Examples
use dbc_rs::Dbc;
let dbc_content = r#"VERSION "1.0"
BU_: ECM TCM
BO_ 256 EngineData : 8 ECM
SG_ RPM : 0|16@0+ (0.25,0) [0|8000] "rpm" TCM
"#;
let dbc = Dbc::parse(dbc_content)?;
println!("Parsed {} messages", dbc.messages().len());Implementations§
Source§impl Dbc
Decoding functionality for DBC structures
impl Dbc
Decoding functionality for DBC structures
Sourcepub fn decode(
&self,
id: u32,
payload: &[u8],
is_extended: bool,
) -> Result<Vec<DecodedSignal<'_>, { MAX_SIGNALS_PER_MESSAGE }>>
pub fn decode( &self, id: u32, payload: &[u8], is_extended: bool, ) -> Result<Vec<DecodedSignal<'_>, { MAX_SIGNALS_PER_MESSAGE }>>
Decode a CAN message payload using the message ID to find the corresponding message definition.
This is a high-performance method for decoding CAN messages in no_std environments.
It finds the message by ID, then decodes all signals in the message from the payload bytes.
§Arguments
id- The raw CAN message ID (without extended flag)payload- The CAN message payload bytes (up to 64 bytes for CAN FD)is_extended- Whether this is an extended (29-bit) CAN ID
§Returns
Ok(Vec<DecodedSignal>)- A vector of decoded signals with name, value, and unitErr(Error)- If the message ID is not found, payload length doesn’t match DLC, or signal decoding fails
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 256 Engine : 8 ECM
SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
"#)?;
// Decode a CAN message with RPM value of 2000 (raw: 8000 = 0x1F40)
let payload = [0x40, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
let decoded = dbc.decode(256, &payload, false)?; // false = standard CAN ID
assert_eq!(decoded.len(), 1);
assert_eq!(decoded[0].name, "RPM");
assert_eq!(decoded[0].value, 2000.0);
assert_eq!(decoded[0].unit, Some("rpm"));High-performance CAN message decoding optimized for throughput.
Performance optimizations:
- O(1) or O(log n) message lookup via feature-flagged index
- Single-pass signal iteration with inline switch processing
- Stack-allocated switch value storage (no heap allocation)
- Message-level extended multiplexing check to skip per-signal lookups
- Inlined hot paths with early returns
Source§impl Dbc
impl Dbc
Sourcepub fn encode(
&self,
id: u32,
signals: &[(&str, f64)],
is_extended: bool,
) -> Result<Vec<u8, MAX_PAYLOAD_SIZE>>
pub fn encode( &self, id: u32, signals: &[(&str, f64)], is_extended: bool, ) -> Result<Vec<u8, MAX_PAYLOAD_SIZE>>
Encode signal values into a CAN message payload.
This is the inverse of Dbc::decode(). It takes a list of signal names
and their physical values, and produces a raw CAN message payload ready
for transmission.
§Arguments
id- The raw CAN message ID (without extended flag)signals- Slice of (signal_name, physical_value) tuples to encodeis_extended- Whether this is an extended (29-bit) CAN ID
§Returns
Ok(Vec<u8, 64>)- The encoded payload, sized according to message DLCErr(Error)- If message not found, signal not found, or value out of range
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 256 Engine : 8 ECM
SG_ RPM : 0|16@1+ (0.25,0) [0|8000] "rpm" *
SG_ Temp : 16|8@1- (1,-40) [-40|215] "°C" *
"#)?;
// Encode RPM=2000 and Temp=50°C
let payload = dbc.encode(256, &[("RPM", 2000.0), ("Temp", 50.0)], false)?;
// The payload can now be transmitted over CAN
assert_eq!(payload.len(), 8);§Multiplexing
For multiplexed messages, include the multiplexer switch signal in the signal list along with the multiplexed signals you want to encode:
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 300 Sensors : 8 ECM
SG_ SensorID M : 0|8@1+ (1,0) [0|3] ""
SG_ Temperature m0 : 8|16@1- (0.1,-40) [-40|125] "°C" *
SG_ Pressure m1 : 8|16@1+ (0.01,0) [0|655.35] "kPa" *
"#)?;
// Encode temperature reading (SensorID=0)
let payload = dbc.encode(300, &[("SensorID", 0.0), ("Temperature", 25.0)], false)?;Source§impl Dbc
impl Dbc
Sourcepub fn version(&self) -> Option<&Version>
pub fn version(&self) -> Option<&Version>
Get the version of the DBC file
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
if let Some(version) = dbc.version() {
// Version is available
let _ = version.as_str();
}Sourcepub fn bit_timing(&self) -> Option<&BitTiming>
pub fn bit_timing(&self) -> Option<&BitTiming>
Get the bit timing configuration
The BS_ section in DBC files specifies CAN bus timing parameters.
Returns None if the BS_ section was empty or not present.
Returns Some(&BitTiming) if timing parameters were specified.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse("VERSION \"1.0\"\n\nBS_: 500000 : 1,2\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
if let Some(bit_timing) = dbc.bit_timing() {
println!("Baudrate: {:?}", bit_timing.baudrate());
}Sourcepub fn nodes(&self) -> &Nodes
pub fn nodes(&self) -> &Nodes
Get a reference to the nodes collection
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM TCM\n\nBO_ 256 Engine : 8 ECM")?;
let nodes = dbc.nodes();
assert_eq!(nodes.len(), 2);
// Iterate over nodes
let mut iter = nodes.iter();
assert_eq!(iter.next(), Some("ECM"));
assert_eq!(iter.next(), Some("TCM"));
assert_eq!(iter.next(), None);Sourcepub fn messages(&self) -> &Messages
pub fn messages(&self) -> &Messages
Get a reference to the messages collection
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
let messages = dbc.messages();
assert_eq!(messages.len(), 1);
let message = messages.at(0).unwrap();
assert_eq!(message.name(), "Engine");
assert_eq!(message.id(), 256);Sourcepub fn value_descriptions(&self) -> &ValueDescriptionsMap
pub fn value_descriptions(&self) -> &ValueDescriptionsMap
Get value descriptions for a specific signal
Value descriptions map numeric signal values to human-readable text.
Returns None if the signal has no value descriptions.
Global Value Descriptions: According to the Vector DBC specification,
a message_id of -1 (0xFFFFFFFF) in a VAL_ statement means the value
descriptions apply to all signals with that name in ANY message. This
method will first check for a message-specific entry, then fall back to
a global entry if one exists.
§Examples
if let Some(value_descriptions) = dbc.value_descriptions_for_signal(100, "Gear") {
if let Some(desc) = value_descriptions.get(0) {
println!("Value 0 means: {}", desc);
}
}Get a reference to the value descriptions list
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 100 Engine : 8 ECM
SG_ Gear : 0|8@1+ (1,0) [0|5] "" *
VAL_ 100 Gear 0 "Park" 1 "Drive" ;"#)?;
let value_descriptions_list = dbc.value_descriptions();
assert_eq!(value_descriptions_list.len(), 1);pub fn value_descriptions_for_signal( &self, message_id: u32, signal_name: &str, ) -> Option<&ValueDescriptions>
Sourcepub fn extended_multiplexing(&self) -> &[ExtendedMultiplexing]
pub fn extended_multiplexing(&self) -> &[ExtendedMultiplexing]
Get all extended multiplexing entries
Returns a reference to all extended multiplexing (SG_MUL_VAL_) entries in the DBC file.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 500 MuxMessage : 8 ECM
SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
SG_ Signal_A m0 : 16|16@1+ (0.1,0) [0|100] ""
SG_MUL_VAL_ 500 Signal_A Mux1 0-5 ;
"#)?;
let ext_mux = dbc.extended_multiplexing();
assert_eq!(ext_mux.len(), 1);Sourcepub fn extended_multiplexing_for_message(
&self,
message_id: u32,
) -> impl Iterator<Item = &ExtendedMultiplexing> + '_
pub fn extended_multiplexing_for_message( &self, message_id: u32, ) -> impl Iterator<Item = &ExtendedMultiplexing> + '_
Get extended multiplexing entries for a specific message
Extended multiplexing (SG_MUL_VAL_) entries define which multiplexer switch values activate specific multiplexed signals. This method returns an iterator over references to extended multiplexing entries for the given message ID.
§Performance
Returns an iterator of references (zero allocation) instead of cloning entries. This is optimized for the decode hot path where extended multiplexing is checked on every CAN frame.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 500 ComplexMux : 8 ECM
SG_ Mux1 M : 0|8@1+ (1,0) [0|255] ""
SG_ Signal_A m0 : 16|16@1+ (0.1,0) [0|100] ""
SG_MUL_VAL_ 500 Signal_A Mux1 0-5,10-15 ;
"#)?;
let extended: Vec<_> = dbc.extended_multiplexing_for_message(500).collect();
assert_eq!(extended.len(), 1);Sourcepub fn comment(&self) -> Option<&str>
pub fn comment(&self) -> Option<&str>
Returns the database-level comment from CM_ (general comment), if present.
This is the general comment for the entire DBC file, not associated with any specific node, message, or signal.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 256 Engine : 8 ECM
CM_ "CAN database for powertrain";"#)?;
assert_eq!(dbc.comment(), Some("CAN database for powertrain"));Sourcepub fn node_comment(&self, node_name: &str) -> Option<&str>
pub fn node_comment(&self, node_name: &str) -> Option<&str>
Returns the comment for a specific node from CM_ BU_ entry, if present.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 256 Engine : 8 ECM
CM_ BU_ ECM "Engine Control Module";"#)?;
assert_eq!(dbc.node_comment("ECM"), Some("Engine Control Module"));Source§impl Dbc
impl Dbc
Sourcepub fn attribute_definitions(&self) -> &AttributeDefinitionsMap
pub fn attribute_definitions(&self) -> &AttributeDefinitionsMap
Get all attribute definitions (BA_DEF_ entries).
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 256 Engine : 8 ECM
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 10000;"#)?;
assert_eq!(dbc.attribute_definitions().len(), 1);Sourcepub fn attribute_definition(&self, name: &str) -> Option<&AttributeDefinition>
pub fn attribute_definition(&self, name: &str) -> Option<&AttributeDefinition>
Get an attribute definition by name.
Sourcepub fn attribute_defaults(&self) -> &AttributeDefaultsMap
pub fn attribute_defaults(&self) -> &AttributeDefaultsMap
Get all attribute defaults (BA_DEF_DEF_ entries).
Sourcepub fn attribute_default(&self, name: &str) -> Option<&AttributeValue>
pub fn attribute_default(&self, name: &str) -> Option<&AttributeValue>
Get the default value for an attribute by name.
Sourcepub fn attribute_values(&self) -> &AttributeValuesMap
pub fn attribute_values(&self) -> &AttributeValuesMap
Get all attribute values (BA_ entries).
Sourcepub fn network_attribute(&self, name: &str) -> Option<&AttributeValue>
pub fn network_attribute(&self, name: &str) -> Option<&AttributeValue>
Get a network-level attribute value by name.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 256 Engine : 8 ECM
BA_DEF_ "BusType" STRING;
BA_DEF_DEF_ "BusType" "";
BA_ "BusType" "CAN";"#)?;
if let Some(value) = dbc.network_attribute("BusType") {
assert_eq!(value.as_string(), Some("CAN"));
}Sourcepub fn node_attribute(
&self,
node_name: &str,
attr_name: &str,
) -> Option<&AttributeValue>
pub fn node_attribute( &self, node_name: &str, attr_name: &str, ) -> Option<&AttributeValue>
Get a node attribute value by node name and attribute name.
Sourcepub fn message_attribute(
&self,
message_id: u32,
attr_name: &str,
) -> Option<&AttributeValue>
pub fn message_attribute( &self, message_id: u32, attr_name: &str, ) -> Option<&AttributeValue>
Get a message attribute value by message ID and attribute name.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse(r#"VERSION "1.0"
BU_: ECM
BO_ 256 Engine : 8 ECM
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 10000;
BA_DEF_DEF_ "GenMsgCycleTime" 0;
BA_ "GenMsgCycleTime" BO_ 256 100;"#)?;
if let Some(value) = dbc.message_attribute(256, "GenMsgCycleTime") {
assert_eq!(value.as_int(), Some(100));
}Sourcepub fn signal_attribute(
&self,
message_id: u32,
signal_name: &str,
attr_name: &str,
) -> Option<&AttributeValue>
pub fn signal_attribute( &self, message_id: u32, signal_name: &str, attr_name: &str, ) -> Option<&AttributeValue>
Get a signal attribute value by message ID, signal name, and attribute name.
Sourcepub fn network_attribute_or_default(
&self,
name: &str,
) -> Option<&AttributeValue>
pub fn network_attribute_or_default( &self, name: &str, ) -> Option<&AttributeValue>
Get a network attribute value with fallback to default.
First checks for a specific value assignment, then falls back to the attribute’s default value if no specific assignment exists.
Sourcepub fn node_attribute_or_default(
&self,
node_name: &str,
attr_name: &str,
) -> Option<&AttributeValue>
pub fn node_attribute_or_default( &self, node_name: &str, attr_name: &str, ) -> Option<&AttributeValue>
Get a node attribute value with fallback to default.
Sourcepub fn message_attribute_or_default(
&self,
message_id: u32,
attr_name: &str,
) -> Option<&AttributeValue>
pub fn message_attribute_or_default( &self, message_id: u32, attr_name: &str, ) -> Option<&AttributeValue>
Get a message attribute value with fallback to default.
Sourcepub fn signal_attribute_or_default(
&self,
message_id: u32,
signal_name: &str,
attr_name: &str,
) -> Option<&AttributeValue>
pub fn signal_attribute_or_default( &self, message_id: u32, signal_name: &str, attr_name: &str, ) -> Option<&AttributeValue>
Get a signal attribute value with fallback to default.
Source§impl Dbc
impl Dbc
Sourcepub fn parse(data: &str) -> Result<Self>
pub fn parse(data: &str) -> Result<Self>
Parse a DBC file from a string slice
§Examples
use dbc_rs::Dbc;
let dbc_content = r#"VERSION "1.0"
BU_: ECM
BO_ 256 EngineData : 8 ECM
SG_ RPM : 0|16@0+ (0.25,0) [0|8000] "rpm""#;
let dbc = Dbc::parse(dbc_content)?;
assert_eq!(dbc.messages().len(), 1);Sourcepub fn parse_bytes(data: &[u8]) -> Result<Self>
pub fn parse_bytes(data: &[u8]) -> Result<Self>
Parse a DBC file from a byte slice
§Examples
use dbc_rs::Dbc;
let dbc_bytes = b"VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM";
let dbc = Dbc::parse_bytes(dbc_bytes)?;
println!("Parsed {} messages", dbc.messages().len());Source§impl Dbc
impl Dbc
Sourcepub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self>
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self>
Load and parse a DBC file from disk.
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::from_file("path/to/file.dbc")?;
println!("Loaded {} messages", dbc.messages().len());Sourcepub fn to_dbc_string(&self) -> String
pub fn to_dbc_string(&self) -> String
Serialize this DBC to a DBC format string
§Examples
use dbc_rs::Dbc;
let dbc = Dbc::parse("VERSION \"1.0\"\n\nBU_: ECM\n\nBO_ 256 Engine : 8 ECM")?;
let dbc_string = dbc.to_dbc_string();
// The string can be written to a file or used elsewhere
assert!(dbc_string.contains("VERSION"));