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 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 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);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 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"));Trait Implementations§
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§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)