Skip to main content

Parser

Struct Parser 

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

A CAN message parser that uses DBC file definitions.

The parser loads message and signal definitions from DBC files and uses them to decode raw CAN frame data into structured messages with physical signal values.

§Example

use can_decode::Parser;
use std::path::Path;

let mut parser = Parser::new();
parser.add_from_dbc_file(Path::new("engine.dbc"))?;
parser.add_from_dbc_file(Path::new("transmission.dbc"))?;

let data = [0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70];
if let Some(decoded) = parser.decode_msg(0x100, &data) {
    println!("Decoded message: {}", decoded.name);
}

Implementations§

Source§

impl Parser

Source

pub fn new() -> Self

Creates a new empty parser.

Use add_from_dbc_file or add_from_str to add message definitions.

§Example
use can_decode::Parser;

let parser = Parser::new();
Source

pub fn from_dbc_file(path: &Path) -> Result<Self, Box<dyn Error>>

Creates a parser and loads definitions from a DBC file.

This is a convenience method that combines new and add_from_str.

§Arguments
  • path - Path to the DBC file
§Errors

Returns an error if the file cannot be read or parsed.

§Example
use can_decode::Parser;
use std::path::Path;

let parser = Parser::from_dbc_file(Path::new("my_database.dbc"))?;
Source

pub fn add_from_str(&mut self, buffer: &str) -> Result<(), Box<dyn Error>>

Adds message definitions from a DBC file string.

This method parses DBC content from a string slice and adds all message definitions to the parser. If a message ID already exists, it will be overwritten and a warning will be logged.

§Arguments
  • buffer - String slice containing the full DBC file contents
§Errors

Returns an error if the DBC content cannot be parsed.

§Example
use can_decode::Parser;

let dbc_content = "VERSION \"\"..."; // DBC file content as &str
let mut parser = Parser::new();
parser.add_from_str(dbc_content)?;
Source

pub fn add_from_dbc_file(&mut self, path: &Path) -> Result<(), Box<dyn Error>>

Adds message definitions from a DBC file.

Reads and parses a DBC file from disk, adding all message definitions to the parser. Multiple DBC files can be loaded to combine definitions from different sources.

§Arguments
  • path - Path to the DBC file
§Errors

Returns an error if the file cannot be read or parsed.

§Example
use can_decode::Parser;
use std::path::Path;

let mut parser = Parser::new();
parser.add_from_dbc_file(Path::new("vehicle.dbc"))?;
parser.add_from_dbc_file(Path::new("diagnostics.dbc"))?;
Source

pub fn decode_msg(&self, msg_id: u32, data: &[u8]) -> Option<DecodedMessage>

Decodes a raw CAN message into structured data.

Takes a CAN message ID and raw data bytes, then decodes all signals according to the DBC definitions. Each signal is extracted, scaled, and converted to its physical value.

§Arguments
  • msg_id - The CAN message identifier
  • data - The raw message data bytes (typically 0-8 bytes for standard CAN)
§Returns

Returns Some(DecodedMessage) if the message ID is known, or None if the message ID is not found in the loaded DBC definitions.

§Example
use can_decode::Parser;
use std::path::Path;

let parser = Parser::from_dbc_file(Path::new("my_database.dbc"))?;

let msg_id = 0x123;
let data = [0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0];

if let Some(decoded) = parser.decode_msg(msg_id, &data) {
    println!("Message: {} (ID: {:#X})", decoded.name, decoded.msg_id);
    for (name, signal) in &decoded.signals {
        println!("  {}: {} {}", name, signal.value, signal.unit);
    }
} else {
    println!("Unknown message ID: {:#X}", msg_id);
}
Source

pub fn encode_msg( &self, msg_id: u32, signal_values: &HashMap<String, f64>, ) -> Option<Vec<u8>>

Encodes a CAN message from signal values into raw bytes.

Takes a message ID and a map of signal names to their physical values, then encodes them according to the DBC definitions into raw CAN data bytes. Applies inverse scaling (offset and factor) and packs bits according to the signal’s byte order and position. Applies scaling factors.

§Arguments
  • msg_id - The CAN message identifier
  • signal_values - Map of signal names to their physical values
§Returns

Returns Some(Vec<u8>) containing the encoded message data, or None if the message ID is not found in the loaded DBC definitions or encoding fails.

§Example
use can_decode::Parser;
use std::path::Path;
use std::collections::HashMap;

let parser = Parser::from_dbc_file(Path::new("my_database.dbc"))?;

let signal_values = HashMap::from([
    ("EngineSpeed".to_string(), 2500.0),
    ("ThrottlePosition".to_string(), 45.5),
]);

if let Some(data) = parser.encode_msg(0x123, &signal_values) {
    println!("Encoded data: {:02X?}", data);
}
Source

pub fn encode_msg_by_name( &self, msg_name: &str, signal_values: &HashMap<String, f64>, ) -> Option<(u32, Vec<u8>)>

Encodes a CAN message by message name instead of ID.

Looks up the message by name and then encode it. This is slower as it requires searching through all loaded messages. Applies scaling factors.

§Arguments
  • msg_name - The name of the message as defined in the DBC file
  • signal_values - Map of signal names to their physical values
§Returns

Returns Some((msg_id, data)) containing the message ID and encoded data, or None if the message name is not found or encoding fails.

§Example
use can_decode::Parser;
use std::path::Path;
use std::collections::HashMap;

let parser = Parser::from_dbc_file(Path::new("my_database.dbc"))?;

let signal_values = HashMap::from([
    ("EngineSpeed".to_string(), 2500.0),
    ("ThrottlePosition".to_string(), 45.5),
]);

if let Some((msg_id, data)) = parser.encode_msg_by_name("EngineData", &signal_values) {
    println!("Message ID: {:#X}, Data: {:02X?}", msg_id, data);
}
Source

pub fn signal_defs(&self, msg_id: u32) -> Option<Vec<Signal>>

Returns all signal definitions for a given message ID.

§Arguments
  • msg_id - The CAN message identifier
§Returns

Returns Some(Vec<Signal>) if the message ID is known, or None otherwise.

§Example
use can_decode::Parser;
use std::path::Path;

let parser = Parser::from_dbc_file(Path::new("my_database.dbc"))?;

if let Some(signals) = parser.signal_defs(0x123) {
    for signal in signals {
        println!("Signal: {}", signal.name);
    }
}
Source

pub fn msg_defs(&self) -> Vec<Message>

Returns all loaded message definitions.

§Returns

A vector containing all message definitions that have been loaded from DBC files.

§Example
use can_decode::Parser;
use std::path::Path;

let parser = Parser::from_dbc_file(Path::new("my_database.dbc"))?;

for msg in parser.msg_defs() {
    println!("Message: {} (ID: {:#X})", msg.name,
             match msg.id {
                 can_dbc::MessageId::Standard(id) => id as u32,
                 can_dbc::MessageId::Extended(id) => id,
             });
}
Source

pub fn msg_def(&self, msg_id: u32) -> Option<&Message>

Returns the message definition for a given message ID.

§Arguments
  • msg_id - The CAN message identifier
§Returns

Returns a reference to the message definition if found, or None if the message ID is not known.

§Example
use can_decode::Parser;
use std::path::Path;

let parser = Parser::from_dbc_file(Path::new("my_database.dbc"))?;

if let Some(msg_def) = parser.msg_def(0x123) {
    println!("Message: {}", msg_def.name);
}
Source

pub fn clear(&mut self)

Clears all loaded message definitions.

After calling this method, the parser will have no message definitions and will need to reload DBC files.

§Example
use can_decode::Parser;

let mut parser = Parser::new();
parser.clear();

Trait Implementations§

Source§

impl Default for Parser

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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.