moondbc

    A DBC parser and CAN signal codec toolkit written in MoonBit.

    dbc
    can
    automotive
    parser
    codec
    Download zip
    Author
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    13 hours ago
    Downloads
    1

    #MoonDBC

    MoonDBC is a DBC parser and CAN signal codec toolkit written in MoonBit. It is intended for automotive gateways, battery-management systems, robotics, test benches, and browser-based diagnostic tools that need to turn raw CAN frames into named engineering values.

    Start with the five-minute demonstration to validate a real DBC, decode a CAN log, review compatibility and try the local workbench. For a larger, externally hosted vehicle capture, see the real CAN capture walkthrough, including measured DBC coverage and data provenance.

    The current milestone provides a portable DBC data model, parsing for messages, signals, signal groups, environment variables, comments, attributes and local or global value tables, source-line diagnostics, and Intel/Motorola signal encoding and decoding. The parser recognizes VERSION, BU_, BO_, BO_TX_BU_, SG_, SG_MUL_VAL_, SIG_GROUP_, SIG_VALTYPE_, EV_, ENVVAR_DATA_, CM_, BA_DEF_, BA_DEF_DEF_, BA_, VAL_, and VAL_TABLE_ declarations, including standard and 29-bit extended frame identifiers, multiple transmitters, integer and IEEE-754 Float32/Float64 signals, byte order, signedness, scale, offset, range, unit, receivers, basic and range-based single-selector multiplexing, named signal groups, reusable global enum tables, environment-variable metadata, documentation comments, scoped attributes, and enum labels. NS_ namespace listings and an empty BS_: header are accepted as structural metadata. Other declarations are reported as unsupported instead of silently discarded; relationship attributes and nested/multiple-selector multiplexing are not implemented.

    #Quick start

    let source =
    #|BO_ 256 Powertrain: 8 ECU
    #| SG_ EngineSpeed : 0|16@1+ (0.125,0) [0|8000] "rpm" Dashboard
    let result = @moondbc.parse(source)
    if result.is_valid() {
    let message = result.database.find_message(256U).unwrap()
    let signal = message.find_signal("EngineSpeed").unwrap()
    let speed = signal.decode(b"\x40\x1f\x00\x00\x00\x00\x00\x00").unwrap()
    println("\{message.name}: \{speed} rpm")
    }

    For extended messages, Message.id preserves the bit-31 DBC identifier used by cross-references. Use Message::frame_id and Message::is_extended_frame when constructing or matching CAN bus frames.

    Timestamped candump records can be decoded without preprocessing:

    let trace = result.database.decode_trace(
    "(1697042645.123456) can0 100##1401F000000000000",
    )
    let csv = trace.to_csv().unwrap()

    Source-aware parsing can drive bit-layout views and editors without adding location fields to the semantic DBC model. Message, signal, and comment declarations are available through the source map:

    let parsed = @moondbc.parse_with_source_map(source)
    let layout = parsed.analyze_frame_layout(256U).unwrap()
    let first_bit = layout.find_cell(0, 0).unwrap()
    for owner in first_bit.owners {
    println("\{owner.signal_name} bit \{owner.signal_bit}")
    }

    Each layout cell is classified as unused, singly occupied, shared by mutually exclusive multiplex branches, or conflicting. Invalid and out-of-payload signals retain their original declaration ranges in layout issues. parsed.locate_validation_issues() also attaches source ranges to semantic failures such as overlapping signals; issues without a retained declaration location explicitly report no source range. For two parsed revisions, before.diff_with_locations(after) pairs each structural change with the old and new declaration ranges, including VAL_ value tables.

    Clone the repository and install its declared dependencies with the current MoonBit toolchain:

    git clone https://github.com/cn-cheems/MoonDBC.git cd MoonDBC moon update

    Run the example and tests:

    moon run cmd/main moon run cmd/codegen moon check --target wasm --deny-warn moon test --target wasm --deny-warn

    #Browser workbench

    MoonDBC includes a local browser workbench for inspecting DBC source, parser and semantic diagnostics, messages, signals, and source-aware CAN frame layouts. It also decodes a pasted SocketCAN frame or timestamped candump record into physical signal values; the built-in sample frame is ready to inspect on launch. Parsing and decoding run in the browser; DBC and CAN data are not uploaded.

    moon install moonbit-community/warren warren dev --browser-entry workbench

    Warren's native installer requires a system C compiler. On Windows without one, run these commands in WSL with GCC installed, or install a compatible C compiler first.

    Open the local URL printed by Warren. The workbench starts with a multiplexed sample and accepts pasted DBC text or local .dbc files up to 4 MiB. Imported files stay in the browser and are not uploaded.

    For a quick demonstration, keep the built-in sample DBC and frame 100#401F7D0100000000. The workbench shows Powertrain values of 2000 rpm, 85 degC and gear 1. Replace the DBC or frame text to inspect your own data; an unknown ID, malformed frame or short payload is reported in place.

    Inspect a real DBC file with the native command-line tool:

    moon run --target native cmd/moondbc -- check examples/vehicle.dbc moon run --target native cmd/moondbc -- list examples/vehicle.dbc moon run --target native cmd/moondbc -- decode examples/vehicle.dbc examples/vehicle.log moon run --target native cmd/moondbc -- summary examples/vehicle.dbc examples/vehicle.log moon run --target native cmd/moondbc -- encode examples/vehicle.dbc 100 EngineSpeed=1000 CoolantTemp=85 Gear=1 moon run --target native cmd/moondbc -- format examples/vehicle.dbc moon run --target native cmd/moondbc -- format --check examples/vehicle.dbc moon run --target native cmd/moondbc -- diff examples/vehicle.dbc examples/vehicle-v2.dbc moon run --target native cmd/moondbc -- generate examples/vehicle.dbc > vehicle_constants.mbt moon run --target native cmd/moondbc -- generate-codecs examples/vehicle.dbc > vehicle_codecs.mbt

    encode accepts a hexadecimal bus identifier followed by one or more NAME=NUMBER physical signal assignments. Use one to three identifier digits for a standard frame and pad to at least four digits for an extended frame.

    format writes a deterministic DBC representation to standard output. Its --check mode produces no output when the file is canonical and exits with status 4 when formatting changes are required, making it suitable for CI. Declarations outside the currently supported syntax are rejected rather than silently removed.

    diff writes a Markdown compatibility report. It exits with status 3 when breaking changes are present, so the command can act as a CI compatibility gate. Each changed message, signal, comment, or value table includes its old and/or new declaration line in the report. All CLI commands that validate a DBC include source line and column for locatable semantic errors, so malformed layouts can be found directly from CI output. summary reports decoded frames and signals separately from unknown IDs, malformed records and short payloads. It exits nonzero for malformed or undecodable known frames, while allowing partial DBC coverage from unknown IDs.

    The extended multiplexing example uses SG_MUL_VAL_ to activate the same signal in multiple selector ranges. Those ranges are used consistently by frame encoding, decoding, overlap validation, layout analysis, deterministic DBC writing, and generated metadata. This milestone supports one multiplexer per message; nested or independent selector trees require a different model and are not claimed as supported. Selector values in the current public model are nonnegative 32-bit Int values.

    Attribute definitions, defaults, and explicit assignments are retained in Database.attributes. Database::attribute_value resolves an explicit value or the definition's default for an existing database, node, message, or signal target. Supported attribute types are INT, HEX, FLOAT, STRING, and ENUM. The strict parser rejects unknown references, scope mismatches, and unsupported attribute syntax instead of dropping metadata. The pinned opendbc fixtures exercise these paths against real vehicle DBC files; the upstream MIT notice is included there.

    generate-codecs emits named MoonBit encode and decode functions for each signal. The destination package must import cn-cheems/moondbc as @moondbc. The functions do not parse DBC text at runtime and operate on individual signals; use the existing frame API for multiplex branch selection. The checked-in generated codec example is compiled and tested on the supported targets.

    #Current scope

    • DBC environment variables (EV_ and ENVVAR_DATA_) with type, bounds, initial value, access metadata, optional data size, source locations, validation, deterministic export, and compatibility reports;
    • Environment-variable CM_ EV_ comments are preserved; environment-variable value descriptions and attribute assignments are not yet supported and remain explicit parse errors;
    • typed models for databases, messages, signals, byte order, signedness, and multiplexing;
    • parsing of core message and signal declarations;
    • deferred resolution of VAL_ value descriptions and label lookup;
    • reusable VAL_TABLE_ enumerations with lookup, source locations, compatibility reports, and deterministic export;
    • named SIG_GROUP_ metadata with reference validation, lookup, and deterministic export;
    • database, node, message, signal, and environment-variable CM_ comments with reference validation;
    • scoped DBC attribute definitions, defaults, assignments, lookup, and deterministic export;
    • multi-transmitter messages through deferred BO_TX_BU_ resolution;
    • bit-31 DBC extended-frame identifiers with collision-safe SocketCAN lookup;
    • bit-accurate Intel and Motorola signal extraction across byte boundaries;
    • signed value extension and factor/offset conversion;
    • IEEE-754 Float32 and Float64 decoding and encoding through SIG_VALTYPE_ declarations;
    • raw and physical signal encoding without mutating the input payload;
    • type, width, frame, scale, and physical range validation;
    • message-level frame decoding with multiplex selector dispatch;
    • inclusive, discontiguous SG_MUL_VAL_ selector ranges with deferred reference resolution;
    • message-level frame encoding from strict named signal assignments;
    • automatic enrichment of decoded values with VAL_ labels;
    • semantic validation for frame bounds, overlaps, scaling, and multiplexing;
    • source-aware CAN payload layout analysis with multiplex sharing and conflict classification;
    • deterministic model comparison for messages, signals, and value tables;
    • compatibility impact classification and deterministic Markdown change reports;
    • standalone MoonBit constant generation for static CAN metadata;
    • named, statically configured MoonBit signal codec generation;
    • deterministic DBC export with parse-write-parse round-trip support;
    • Classical CAN and CAN FD SocketCAN/candump parsing, formatting, and direct decoding;
    • recoverable multi-frame trace decoding and CSV signal export;
    • concise trace coverage summaries for matching recorded traffic against a DBC;
    • recoverable diagnostics for malformed and misplaced declarations;
    • native check, list, trace-to-CSV decode, coverage summary, physical-value encode, deterministic format, compatibility diff, generate, and generate-codecs commands;
    • duplicate message and signal checks;
    • portable library code for Wasm, Wasm-GC, JavaScript, and native targets.

    #Project origin

    MoonDBC is an original MoonBit implementation of the DBC data model and commonly documented text syntax. It does not copy source code from an existing DBC library. The third-party DBC fixtures are credited with their source and license in their own directory.

    The DBC declaration grammar was checked against the Vector DBC format documentation; the implementation is independent and covers only the declarations listed above. The checked-in codec example is generated by MoonDBC from the repository's own example DBC. The browser workbench uses Rabbita and moonbitlang/async, both Apache-2.0 dependencies declared in moon.mod. The workbench does not require externally hosted JavaScript or font files.

    #License

    Apache-2.0.

    ByteOrder

    pub(all) enum ByteOrder {
    Motorola
    Intel
    } derive(Eq,
    Debug
    )

    DBC uses @0 for Motorola bit order and @1 for Intel bit order.

    ByteOrder::equal

    fn ByteOrder::equal(ByteOrder, ByteOrder) -> Bool

    ByteOrder::not_equal

    fn ByteOrder::not_equal(x : ByteOrder, y : ByteOrder) -> Bool

    CanFrame

    pub(all) struct CanFrame {
    id : UInt
    is_extended_frame : Bool
    payload : Bytes
    } derive(Eq,
    Debug
    )

    A CAN data frame independent of a specific socket or operating system.

    CanFrame::equal

    fn CanFrame::equal(CanFrame, CanFrame) -> Bool

    Keep trait-derived convenience methods available as regular public methods.

    CanFrame::not_equal

    fn CanFrame::not_equal(x : CanFrame, y : CanFrame) -> Bool

    Keep trait-derived convenience methods available as regular public methods.

    CanFrame::to_repr

    CanFrame::to_text

    fn CanFrame::to_text(self : CanFrame) -> Result[String, CanFrameTextError]

    Render a frame as canonical compact SocketCAN text. Standard identifiers use three hexadecimal digits and extended identifiers use eight.

    CanFrameTextError

    pub(all) enum CanFrameTextError {
    CanFrameMissingSeparator
    CanFrameEmptyIdentifier
    CanFrameIdentifierTooLong(Int)
    CanFrameInvalidIdentifier(Int, Char)
    CanFrameIdentifierOutOfRange(UInt)
    CanFrameOddPayloadLength(Int)
    CanFramePayloadTooLong(Int)
    CanFrameInvalidPayload(Int, Char)
    } derive(Eq,
    Debug
    )

    CanFrameTextError::equal

    CanFrameTextError::not_equal

    fn CanFrameTextError::not_equal(x : CanFrameTextError, y : CanFrameTextError) -> Bool

    CanLogRecord

    pub(all) struct CanLogRecord {
    timestamp : String?
    interface_name : String?
    fd_flags : Byte?
    frame : CanFrame
    } derive(Eq,
    Debug
    )

    A compact CAN frame with optional candump timestamp and interface metadata.

    CanLogRecord::equal

    CanLogRecord::not_equal

    fn CanLogRecord::not_equal(x : CanLogRecord, y : CanLogRecord) -> Bool

    CanLogRecord::to_text

    fn CanLogRecord::to_text(self : CanLogRecord) -> Result[String, CanLogTextError]

    Render a log record using the shortest candump form that preserves its timestamp and interface metadata.

    CanLogTextError

    pub(all) enum CanLogTextError {
    CanLogInvalidFieldCount(Int)
    CanLogInvalidTimestamp(String)
    CanLogInvalidInterface(String)
    CanLogMissingFdFlags
    CanLogInvalidFdFlags(String)
    CanLogFdFlagsOutOfRange(Int)
    CanLogTimestampWithoutInterface
    CanLogFrameTextError(CanFrameTextError)
    } derive(Eq,
    Debug
    )

    CanLogTextError::equal

    CanLogTextError::not_equal

    fn CanLogTextError::not_equal(x : CanLogTextError, y : CanLogTextError) -> Bool

    ChangeImpact

    pub(all) enum ChangeImpact {
    Breaking
    NonBreaking
    Informational
    } derive(Eq,
    Debug
    )

    Describes how a database change affects consumers of the older DBC model.

    ChangeImpact::equal

    ChangeImpact::not_equal

    fn ChangeImpact::not_equal(x : ChangeImpact, y : ChangeImpact) -> Bool

    ClassifiedChange

    pub(all) struct ClassifiedChange {
    impact : ChangeImpact
    change : DatabaseChange
    } derive(Eq,
    Debug
    )

    ClassifiedChange::equal

    ClassifiedChange::not_equal

    fn ClassifiedChange::not_equal(x : ClassifiedChange, y : ClassifiedChange) -> Bool

    CliMode

    pub(all) enum CliMode {
    CliCheck
    CliList
    } derive(Eq,
    Debug
    )

    CliMode::equal

    fn CliMode::equal(CliMode, CliMode) -> Bool

    CliMode::not_equal

    fn CliMode::not_equal(x : CliMode, y : CliMode) -> Bool

    CliMode::to_repr

    CliOutput

    pub(all) struct CliOutput {
    stdout : String
    stderr : String
    exit_code : Int
    } derive(Eq,
    Debug
    )

    CliOutput::equal

    fn CliOutput::equal(CliOutput, CliOutput) -> Bool

    CliOutput::not_equal

    fn CliOutput::not_equal(x : CliOutput, y : CliOutput) -> Bool

    CommentSourceLocation

    pub(all) struct CommentSourceLocation {
    target : DbcCommentTarget
    declaration : SourceSpan
    } derive(Eq,
    Debug
    )

    CommentSourceLocation::equal

    CommentSourceLocation::not_equal

    CompatibilityReport

    pub(all) struct CompatibilityReport {
    changes : Array[ClassifiedChange]
    breaking_count : Int
    non_breaking_count : Int
    informational_count : Int
    } derive(Eq,
    Debug
    )

    CompatibilityReport::equal

    CompatibilityReport::has_changes

    fn CompatibilityReport::has_changes(self : CompatibilityReport) -> Bool

    CompatibilityReport::is_backward_compatible

    fn CompatibilityReport::is_backward_compatible(self : CompatibilityReport) -> Bool

    A report remains backward compatible when it contains no breaking changes.

    CompatibilityReport::not_equal

    CompatibilityReport::to_markdown

    fn CompatibilityReport::to_markdown(self : CompatibilityReport) -> String

    Render a deterministic Markdown report for pull requests and CI artifacts.

    Database

    pub(all) struct Database {
    version : String?
    nodes : Array[String]
    messages : Array[Message]
    value_tables : Array[ValueTable]
    global_value_tables : Array[GlobalValueTable]
    environment_variables : Array[EnvironmentVariable]
    signal_groups : Array[SignalGroup]
    comments : Array[DbcComment]
    attributes : DbcAttributes
    } derive(Eq,
    Debug
    )

    Database::analyze_frame_layout

    fn Database::analyze_frame_layout(self : Database, message_id : UInt) -> Result[FrameLayoutAnalysis, FrameLayoutError]

    Analyze the payload bits occupied by every signal. Source ranges are absent for databases that were constructed manually or returned by parse.

    Database::attribute_value

    fn Database::attribute_value(self : Database, name : StringView, target : DbcAttributeTarget) -> DbcAttributeValue?

    Database::can_message_comment

    fn Database::can_message_comment(self : Database, frame_id : UInt, is_extended_frame : Bool) -> String?

    Database::can_signal_comment

    fn Database::can_signal_comment(self : Database, frame_id : UInt, is_extended_frame : Bool, signal_name : StringView) -> String?

    Database::can_value_label

    fn Database::can_value_label(self : Database, frame_id : UInt, is_extended_frame : Bool, signal_name : StringView, value : Int64) -> String?

    Database::compatibility_report

    fn Database::compatibility_report(self : Database, newer : Database) -> CompatibilityReport

    Compare two databases and summarize the compatibility impact of every detected model change.

    Database::database_comment

    fn Database::database_comment(self : Database) -> String?

    Database::decode_can_frame

    fn Database::decode_can_frame(self : Database, frame : CanFrame) -> Result[DecodedMessage, FrameDecodeError]

    Decode a parsed CAN frame using the message identifier in the frame.

    Database::decode_can_payload

    fn Database::decode_can_payload(self : Database, frame_id : UInt, is_extended_frame : Bool, payload : BytesView) -> Result[DecodedMessage, FrameDecodeError]

    Decode a payload using its bus identifier and explicit standard/extended frame format.

    Database::decode_frame

    fn Database::decode_frame(self : Database, message_id : UInt, payload : BytesView) -> Result[DecodedMessage, FrameDecodeError]

    Find and decode a message by its DBC declaration identifier, enriching decoded signals with VAL_ labels. Use decode_can_payload for a bus ID.

    Database::decode_trace

    fn Database::decode_trace(self : Database, source : StringView) -> TraceDecodeResult

    Decode compact SocketCAN frames or candump records line by line. Blank lines and lines starting with // are ignored. Invalid or undecodable lines are retained as diagnostics without preventing later records from being processed.

    Database::diff

    fn Database::diff(self : Database, newer : Database) -> Array[DatabaseChange]

    Compare this database with a newer database. Changes are returned in a deterministic order: global metadata, removals/modifications, then additions.

    Database::encode_can_frame

    fn Database::encode_can_frame(self : Database, frame_id : UInt, is_extended_frame : Bool, assignments : Array[SignalAssignment]) -> Result[CanFrame, FrameEncodeError]

    Build a complete standard or extended CAN frame from named physical values.

    Database::encode_frame

    fn Database::encode_frame(self : Database, message_id : UInt, assignments : Array[SignalAssignment]) -> Result[Bytes, FrameEncodeError]

    Find a message by its DBC declaration identifier and build its CAN payload. Use encode_can_frame when starting from a bus arbitration identifier.

    Database::environment_comment

    fn Database::environment_comment(self : Database, name : StringView) -> String?

    Database::equal

    fn Database::equal(Database, Database) -> Bool

    Database::find_can_message

    fn Database::find_can_message(self : Database, frame_id : UInt, is_extended_frame : Bool) -> Message?

    Find a message by its bus arbitration identifier and frame format.

    Database::find_comment

    fn Database::find_comment(self : Database, target : DbcCommentTarget) -> DbcComment?

    Database::find_environment_variable

    fn Database::find_environment_variable(self : Database, name : StringView) -> EnvironmentVariable?

    Database::find_global_value_table

    fn Database::find_global_value_table(self : Database, name : StringView) -> GlobalValueTable?

    Find a reusable database-level VAL_TABLE_ enumeration by name.

    Database::find_message

    fn Database::find_message(self : Database, id : UInt) -> Message?

    Find a message by the identifier stored in its DBC declaration. For a bus arbitration identifier, use find_can_message.

    Database::find_signal_group

    fn Database::find_signal_group(self : Database, message_id : UInt, name : StringView) -> SignalGroup?

    Find a signal group by its message identifier and group name.

    Database::find_value_table

    fn Database::find_value_table(self : Database, message_id : UInt, signal_name : StringView) -> ValueTable?

    Database::generate_moonbit_constants

    fn Database::generate_moonbit_constants(self : Database) -> String

    Generate standalone MoonBit constants for message identifiers, payload sizes, signal layouts, scaling parameters, multiplexing, and value tables. Names are normalized and include stable numeric suffixes to avoid clashes.

    Database::generate_moonbit_signal_codecs

    fn Database::generate_moonbit_signal_codecs(self : Database) -> Result[String, String]

    Generate named, signal-level encode and decode functions that do not parse DBC text at runtime. The destination package must import this library as @moondbc. Multiplex branch selection remains the caller's responsibility; use Message::decode_frame and Message::encode_frame for whole frames.

    Database::message_comment

    fn Database::message_comment(self : Database, id : UInt) -> String?

    Database::node_comment

    fn Database::node_comment(self : Database, name : StringView) -> String?

    Database::not_equal

    fn Database::not_equal(x : Database, y : Database) -> Bool

    Database::signal_comment

    fn Database::signal_comment(self : Database, message_id : UInt, signal_name : StringView) -> String?

    Database::to_dbc

    fn Database::to_dbc(self : Database) -> Result[String, DbcWriteError]

    Write the supported database model as deterministic DBC text. Structurally invalid models should be checked with Database::validate before export; this method reports values that cannot be represented by the parser syntax.

    Database::to_repr

    Database::validate

    fn Database::validate(self : Database) -> Array[ValidationIssue]

    Validate cross-field and bit-layout constraints that are not syntax errors.

    Database::value_label

    fn Database::value_label(self : Database, message_id : UInt, signal_name : StringView, value : Int64) -> String?

    DatabaseChange

    pub(all) enum DatabaseChange {
    VersionChangedChange(String?, String?)
    NodesChangedChange(Array[String], Array[String])
    CommentAddedChange(DbcComment)
    CommentRemovedChange(DbcComment)
    CommentModifiedChange(DbcCommentTarget, String, String)
    MessageAddedChange(Message)
    MessageRemovedChange(Message)
    MessageMetadataChangedChange(UInt, MessageMetadata, MessageMetadata)
    SignalAddedChange(UInt, Signal)
    SignalRemovedChange(UInt, Signal)
    SignalModifiedChange(UInt, String, Signal, Signal)
    ValueTableAddedChange(ValueTable)
    ValueTableRemovedChange(ValueTable)
    ValueTableModifiedChange(UInt, String, ValueTable, ValueTable)
    GlobalValueTableAddedChange(GlobalValueTable)
    GlobalValueTableRemovedChange(GlobalValueTable)
    GlobalValueTableModifiedChange(String, GlobalValueTable, GlobalValueTable)
    EnvironmentVariableAddedChange(EnvironmentVariable)
    EnvironmentVariableRemovedChange(EnvironmentVariable)
    EnvironmentVariableModifiedChange(String, EnvironmentVariable, EnvironmentVariable)
    SignalGroupAddedChange(SignalGroup)
    SignalGroupRemovedChange(SignalGroup)
    SignalGroupModifiedChange(UInt, String, SignalGroup, SignalGroup)
    AttributesChangedChange(DbcAttributes, DbcAttributes)
    } derive(Eq,
    Debug
    )

    DatabaseChange::equal

    DatabaseChange::impact

    Classify a change from the perspective of software built against the older database. Additions remain compatible, while removals and changed layouts require consumers to review or update their assumptions.

    DatabaseChange::not_equal

    fn DatabaseChange::not_equal(x : DatabaseChange, y : DatabaseChange) -> Bool

    DatabaseChange::summary

    fn DatabaseChange::summary(self : DatabaseChange) -> String

    Render a concise sentence suitable for logs, reviews, and release notes.

    DbcAttributeAssignment

    pub(all) struct DbcAttributeAssignment {
    name : String
    target : DbcAttributeTarget
    value : DbcAttributeValue
    } derive(Eq,
    Debug
    )

    DbcAttributeAssignment::equal

    DbcAttributeAssignment::not_equal

    DbcAttributeDefault

    pub(all) struct DbcAttributeDefault {
    name : String
    value : DbcAttributeValue
    } derive(Eq,
    Debug
    )

    DbcAttributeDefault::equal

    DbcAttributeDefault::not_equal

    DbcAttributeDefinition

    pub(all) struct DbcAttributeDefinition {
    name : String
    scope : DbcAttributeScope
    value_type : DbcAttributeType
    } derive(Eq,
    Debug
    )

    DbcAttributeDefinition::equal

    DbcAttributeDefinition::not_equal

    DbcAttributeScope

    pub(all) enum DbcAttributeScope {
    DatabaseAttributeScope
    NodeAttributeScope
    MessageAttributeScope
    SignalAttributeScope
    } derive(Eq,
    Debug
    )

    DbcAttributeScope::equal

    DbcAttributeScope::not_equal

    fn DbcAttributeScope::not_equal(x : DbcAttributeScope, y : DbcAttributeScope) -> Bool

    DbcAttributeTarget

    pub(all) enum DbcAttributeTarget {
    DatabaseAttributeTarget
    NodeAttributeTarget(String)
    MessageAttributeTarget(UInt)
    SignalAttributeTarget(UInt, String)
    } derive(Eq,
    Debug
    )

    DbcAttributeTarget::equal

    DbcAttributeTarget::not_equal

    DbcAttributeType

    pub(all) enum DbcAttributeType {
    AttributeIntegerType(Int64, Int64)
    AttributeHexType(Int64, Int64)
    AttributeFloatType(Double, Double)
    AttributeStringType
    AttributeEnumType(Array[String])
    } derive(Eq,
    Debug
    )

    DbcAttributeType::equal

    DbcAttributeType::not_equal

    fn DbcAttributeType::not_equal(x : DbcAttributeType, y : DbcAttributeType) -> Bool

    DbcAttributeValue

    pub(all) enum DbcAttributeValue {
    AttributeInteger(Int64)
    AttributeFloat(Double)
    AttributeText(String)
    } derive(Eq,
    Debug
    )

    DbcAttributeValue::equal

    DbcAttributeValue::not_equal

    fn DbcAttributeValue::not_equal(x : DbcAttributeValue, y : DbcAttributeValue) -> Bool

    DbcAttributes

    pub(all) struct DbcAttributes {
    definitions : Array[DbcAttributeDefinition]
    defaults : Array[DbcAttributeDefault]
    assignments : Array[DbcAttributeAssignment]
    } derive(Eq,
    Debug
    )

    DbcAttributes::empty

    DbcAttributes::equal

    DbcAttributes::not_equal

    fn DbcAttributes::not_equal(x : DbcAttributes, y : DbcAttributes) -> Bool

    DbcComment

    pub(all) struct DbcComment {
    target : DbcCommentTarget
    text : String
    } derive(Eq,
    Debug
    )

    DbcComment::equal

    fn DbcComment::equal(DbcComment, DbcComment) -> Bool

    DbcComment::not_equal

    fn DbcComment::not_equal(x : DbcComment, y : DbcComment) -> Bool

    DbcCommentTarget

    pub(all) enum DbcCommentTarget {
    DatabaseComment
    NodeComment(String)
    MessageComment(UInt)
    SignalComment(UInt, String)
    EnvironmentComment(String)
    } derive(Eq,
    Debug
    )

    DbcCommentTarget::equal

    DbcCommentTarget::not_equal

    fn DbcCommentTarget::not_equal(x : DbcCommentTarget, y : DbcCommentTarget) -> Bool

    DbcSourceMap

    pub(all) struct DbcSourceMap {
    messages : Array[MessageSourceLocation]
    signals : Array[SignalSourceLocation]
    comments : Array[CommentSourceLocation]
    value_tables : Array[ValueTableSourceLocation]
    global_value_tables : Array[GlobalValueTableSourceLocation]
    environment_variables : Array[EnvironmentVariableSourceLocation]
    signal_groups : Array[SignalGroupSourceLocation]
    } derive(Eq,
    Debug
    )

    Source locations are kept separately from the semantic model so manually constructed databases and existing parse callers remain source-agnostic.

    DbcSourceMap::equal

    DbcSourceMap::find_comment

    fn DbcSourceMap::find_comment(self : DbcSourceMap, target : DbcCommentTarget) -> SourceSpan?

    DbcSourceMap::find_environment_variable

    fn DbcSourceMap::find_environment_variable(self : DbcSourceMap, name : StringView) -> SourceSpan?

    DbcSourceMap::find_global_value_table

    fn DbcSourceMap::find_global_value_table(self : DbcSourceMap, name : StringView) -> SourceSpan?

    DbcSourceMap::find_message

    fn DbcSourceMap::find_message(self : DbcSourceMap, message_id : UInt) -> SourceSpan?

    DbcSourceMap::find_signal

    fn DbcSourceMap::find_signal(self : DbcSourceMap, message_id : UInt, signal_name : StringView) -> SourceSpan?

    DbcSourceMap::find_signal_group

    fn DbcSourceMap::find_signal_group(self : DbcSourceMap, message_id : UInt, name : StringView) -> SourceSpan?

    DbcSourceMap::find_value_table

    fn DbcSourceMap::find_value_table(self : DbcSourceMap, message_id : UInt, signal_name : StringView) -> SourceSpan?

    DbcSourceMap::not_equal

    fn DbcSourceMap::not_equal(x : DbcSourceMap, y : DbcSourceMap) -> Bool

    DbcWriteError

    pub(all) enum DbcWriteError {
    DbcWriteInvalidToken(String, String)
    DbcWriteInvalidQuotedText(String, String)
    DbcWriteInvalidPayloadSize(UInt, Int)
    DbcWriteNonFiniteSignalNumber(UInt, String, String)
    DbcWriteNegativeMultiplexValue(UInt, String, Int)
    DbcWriteInvalidMultiplexRange(UInt, String, Int, Int)
    DbcWriteEmptyValueTable(UInt, String)
    DbcWriteEmptyGlobalValueTable(String)
    DbcWriteDuplicateTransmitter(UInt, String)
    DbcWriteInvalidMessageIdentifier(UInt)
    DbcWriteInvalidAttribute(String)
    DbcWriteInvalidSignalGroup(UInt, String)
    DbcWriteInvalidEnvironmentVariable(String)
    } derive(Eq,
    Debug
    )

    DbcWriteError::equal

    DbcWriteError::not_equal

    fn DbcWriteError::not_equal(x : DbcWriteError, y : DbcWriteError) -> Bool

    DecodeError

    pub(all) enum DecodeError {
    InvalidSignalLayout(Int, Int)
    FrameTooShort(Int, Int)
    } derive(Eq,
    Debug
    )

    DecodeError::equal

    fn DecodeError::equal(DecodeError, DecodeError) -> Bool

    DecodeError::not_equal

    fn DecodeError::not_equal(x : DecodeError, y : DecodeError) -> Bool

    DecodedMessage

    pub(all) struct DecodedMessage {
    id : UInt
    is_extended_frame : Bool
    name : String
    signals : Array[DecodedSignal]
    } derive(Eq,
    Debug
    )

    DecodedMessage::equal

    DecodedMessage::not_equal

    fn DecodedMessage::not_equal(x : DecodedMessage, y : DecodedMessage) -> Bool

    DecodedSignal

    pub(all) struct DecodedSignal {
    name : String
    raw : RawValue
    physical : Double
    unit : String
    label : String?
    } derive(Eq,
    Debug
    )

    DecodedSignal::equal

    DecodedSignal::not_equal

    fn DecodedSignal::not_equal(x : DecodedSignal, y : DecodedSignal) -> Bool

    DecodedTraceFrame

    pub(all) struct DecodedTraceFrame {
    line : Int
    timestamp : String?
    interface_name : String?
    fd_flags : Byte?
    frame : CanFrame
    decoded : DecodedMessage
    } derive(Eq,
    Debug
    )

    DecodedTraceFrame::equal

    DecodedTraceFrame::not_equal

    fn DecodedTraceFrame::not_equal(x : DecodedTraceFrame, y : DecodedTraceFrame) -> Bool

    Diagnostic

    pub(all) struct Diagnostic {
    line : Int
    column : Int
    code : String
    message : String
    } derive(Eq,
    Debug
    )

    Diagnostic::equal

    fn Diagnostic::equal(Diagnostic, Diagnostic) -> Bool

    Diagnostic::not_equal

    fn Diagnostic::not_equal(x : Diagnostic, y : Diagnostic) -> Bool

    EncodeError

    pub(all) enum EncodeError {
    EncodeInvalidLayout(Int, Int)
    EncodeFrameTooShort(Int, Int)
    ValueKindMismatch(ValueKind, RawValue)
    SignalValueTypeMismatch(SignalValueType, RawValue)
    RawValueOutOfRange(RawValue, Int)
    InvalidFactor(Double)
    NonFinitePhysicalValue(Double)
    PhysicalValueOutOfRange(Double, Double, Double)
    PhysicalRawOutOfRange(Double, Int)
    } derive(Eq,
    Debug
    )

    EncodeError::equal

    fn EncodeError::equal(EncodeError, EncodeError) -> Bool

    EncodeError::not_equal

    fn EncodeError::not_equal(x : EncodeError, y : EncodeError) -> Bool

    EnvironmentVariable

    pub(all) struct EnvironmentVariable {
    name : String
    value_type : Int
    minimum : Double
    maximum : Double
    unit : String
    initial_value : Double
    id : UInt
    access_type : Int
    access_nodes : Array[String]
    data_size : UInt?
    } derive(Eq,
    Debug
    )

    DBC environment variable; an optional data size comes from ENVVAR_DATA_.

    EnvironmentVariable::equal

    EnvironmentVariable::not_equal

    EnvironmentVariableSourceLocation

    pub(all) struct EnvironmentVariableSourceLocation {
    name : String
    declaration : SourceSpan
    } derive(Eq,
    Debug
    )

    FrameDecodeError

    pub(all) enum FrameDecodeError {
    UnknownMessage(UInt)
    InvalidCanFrameIdentifier(UInt, Bool)
    UnknownCanMessage(UInt, Bool)
    PayloadTooShort(Int, Int)
    MissingMultiplexer
    MultipleMultiplexers
    SignalDecodeFailed(String, DecodeError)
    } derive(Eq,
    Debug
    )

    FrameDecodeError::equal

    FrameDecodeError::not_equal

    fn FrameDecodeError::not_equal(x : FrameDecodeError, y : FrameDecodeError) -> Bool

    FrameEncodeError

    pub(all) enum FrameEncodeError {
    FrameEncodeUnknownMessage(UInt)
    FrameEncodeInvalidCanIdentifier(UInt, Bool)
    FrameEncodeUnknownCanMessage(UInt, Bool)
    FrameEncodeInvalidPayloadSize(Int)
    FrameEncodeUnknownSignal(String)
    FrameEncodeDuplicateSignal(String)
    FrameEncodeMissingSignal(String)
    FrameEncodeInactiveSignal(String, Int)
    FrameEncodeInactiveRangeSignal(String)
    FrameEncodeMissingMultiplexer
    FrameEncodeMultipleMultiplexers
    FrameSignalEncodeFailed(String, EncodeError)
    FrameMultiplexerDecodeFailed(String, DecodeError)
    } derive(Eq,
    Debug
    )

    FrameEncodeError::equal

    FrameEncodeError::not_equal

    fn FrameEncodeError::not_equal(x : FrameEncodeError, y : FrameEncodeError) -> Bool

    FrameLayoutAnalysis

    pub(all) struct FrameLayoutAnalysis {
    message_id : UInt
    payload_size : Int
    cells : Array[FrameLayoutCell]
    issues : Array[FrameLayoutIssue]
    } derive(Eq,
    Debug
    )

    FrameLayoutAnalysis::equal

    FrameLayoutAnalysis::find_cell

    fn FrameLayoutAnalysis::find_cell(self : FrameLayoutAnalysis, byte_index : Int, bit_in_byte : Int) -> FrameLayoutCell?

    FrameLayoutAnalysis::not_equal

    FrameLayoutCell

    pub(all) struct FrameLayoutCell {
    absolute_bit : Int
    byte_index : Int
    bit_in_byte : Int
    kind : FrameLayoutCellKind
    owners : Array[FrameLayoutOwner]
    } derive(Eq,
    Debug
    )

    FrameLayoutCell::equal

    FrameLayoutCell::not_equal

    fn FrameLayoutCell::not_equal(x : FrameLayoutCell, y : FrameLayoutCell) -> Bool

    FrameLayoutCellKind

    pub(all) enum FrameLayoutCellKind {
    LayoutUnused
    LayoutOccupied
    LayoutMultiplexed
    LayoutConflict
    } derive(Eq,
    Debug
    )

    FrameLayoutCellKind::equal

    FrameLayoutCellKind::not_equal

    FrameLayoutError

    pub(all) enum FrameLayoutError {
    LayoutUnknownMessage(UInt)
    } derive(Eq,
    Debug
    )

    FrameLayoutError::equal

    FrameLayoutError::not_equal

    fn FrameLayoutError::not_equal(x : FrameLayoutError, y : FrameLayoutError) -> Bool

    FrameLayoutIssue

    pub(all) enum FrameLayoutIssue {
    LayoutInvalidPayloadSize(Int)
    LayoutInvalidSignal(String, Int, Int, SourceSpan?)
    LayoutSignalOutsidePayload(String, SourceSpan?)
    LayoutConflictingSignals(String, String, Array[Int], SourceSpan?, SourceSpan?)
    } derive(Eq,
    Debug
    )

    FrameLayoutIssue::equal

    FrameLayoutIssue::not_equal

    fn FrameLayoutIssue::not_equal(x : FrameLayoutIssue, y : FrameLayoutIssue) -> Bool

    FrameLayoutOwner

    pub(all) struct FrameLayoutOwner {
    signal_index : Int
    signal_name : String
    signal_bit : Int
    multiplex : MultiplexRole
    source : SourceSpan?
    } derive(Eq,
    Debug
    )

    FrameLayoutOwner::equal

    FrameLayoutOwner::not_equal

    fn FrameLayoutOwner::not_equal(x : FrameLayoutOwner, y : FrameLayoutOwner) -> Bool

    GlobalValueTable

    pub(all) struct GlobalValueTable {
    name : String
    entries : Array[ValueDescription]
    } derive(Eq,
    Debug
    )

    A reusable named VAL_TABLE_ enumeration declared at database scope.

    GlobalValueTable::equal

    GlobalValueTable::not_equal

    fn GlobalValueTable::not_equal(x : GlobalValueTable, y : GlobalValueTable) -> Bool

    GlobalValueTableSourceLocation

    pub(all) struct GlobalValueTableSourceLocation {
    name : String
    declaration : SourceSpan
    } derive(Eq,
    Debug
    )

    GlobalValueTableSourceLocation::not_equal

    LocatedDatabaseChange

    pub(all) struct LocatedDatabaseChange {
    change : DatabaseChange
    before : SourceSpan?
    after : SourceSpan?
    } derive(Eq,
    Debug
    )

    LocatedDatabaseChange::equal

    LocatedDatabaseChange::not_equal

    LocatedValidationIssue

    pub(all) struct LocatedValidationIssue {
    issue : ValidationIssue
    source : SourceSpan?
    } derive(Eq,
    Debug
    )

    LocatedValidationIssue::equal

    LocatedValidationIssue::not_equal

    Message

    pub(all) struct Message {
    id : UInt
    name : String
    payload_size : Int
    transmitter : String
    additional_transmitters : Array[String]
    signals : Array[Signal]
    } derive(Eq,
    Debug
    )

    Message::decode_frame

    fn Message::decode_frame(self : Message, payload : BytesView) -> Result[DecodedMessage, FrameDecodeError]

    Decode every active signal in a CAN frame. Multiplexed signals are emitted only when their selector matches the decoded multiplexer value.

    Message::encode_frame

    fn Message::encode_frame(self : Message, assignments : Array[SignalAssignment]) -> Result[Bytes, FrameEncodeError]

    Build a zero-initialized CAN payload from named physical signal values. Plain signals and the selected multiplex branch must be assigned exactly once. Assignments for inactive multiplex branches are rejected.

    Message::equal

    fn Message::equal(Message, Message) -> Bool

    Message::find_signal

    fn Message::find_signal(self : Message, name : StringView) -> Signal?

    Message::frame_id

    fn Message::frame_id(self : Message) -> UInt

    Return the arbitration identifier placed on the CAN bus.

    Message::is_extended_frame

    fn Message::is_extended_frame(self : Message) -> Bool

    Return whether the DBC identifier uses the bit-31 extended-frame marker.

    Message::is_transmitted_by

    fn Message::is_transmitted_by(self : Message, node : StringView) -> Bool

    Message::not_equal

    fn Message::not_equal(x : Message, y : Message) -> Bool

    Message::to_repr

    Message::transmitters

    fn Message::transmitters(self : Message) -> Array[String]

    Return the primary transmitter followed by transmitters declared through BO_TX_BU_.

    MessageMetadata

    pub(all) struct MessageMetadata {
    name : String
    payload_size : Int
    transmitter : String
    additional_transmitters : Array[String]
    } derive(Eq,
    Debug
    )

    MessageMetadata::equal

    MessageMetadata::not_equal

    fn MessageMetadata::not_equal(x : MessageMetadata, y : MessageMetadata) -> Bool

    MessageSourceLocation

    pub(all) struct MessageSourceLocation {
    message_id : UInt
    declaration : SourceSpan
    } derive(Eq,
    Debug
    )

    MessageSourceLocation::equal

    MessageSourceLocation::not_equal

    MultiplexRange

    pub(all) struct MultiplexRange {
    start : Int
    end : Int
    } derive(Eq,
    Debug
    )

    Inclusive selector interval in an SG_MUL_VAL_ declaration.

    MultiplexRange::equal

    MultiplexRange::not_equal

    fn MultiplexRange::not_equal(x : MultiplexRange, y : MultiplexRange) -> Bool

    MultiplexRole

    pub(all) enum MultiplexRole {
    Plain
    Multiplexer
    Multiplexed(Int)
    MultiplexedRanges(String, Array[MultiplexRange])
    } derive(Eq,
    Debug
    )

    MultiplexRole::equal

    MultiplexRole::not_equal

    fn MultiplexRole::not_equal(x : MultiplexRole, y : MultiplexRole) -> Bool

    ParseResult

    pub(all) struct ParseResult {
    database : Database
    diagnostics : Array[Diagnostic]
    } derive(Eq,
    Debug
    )

    ParseResult::equal

    fn ParseResult::equal(ParseResult, ParseResult) -> Bool

    ParseResult::is_valid

    fn ParseResult::is_valid(self : ParseResult) -> Bool

    ParseResult::not_equal

    fn ParseResult::not_equal(x : ParseResult, y : ParseResult) -> Bool

    RawValue

    pub(all) enum RawValue {
    UnsignedRaw(UInt64)
    SignedRaw(Int64)
    FloatRaw(Double)
    } derive(Eq,
    Debug
    )

    A raw CAN signal value retains its integer signedness or IEEE-754 value.

    RawValue::equal

    fn RawValue::equal(RawValue, RawValue) -> Bool

    RawValue::not_equal

    fn RawValue::not_equal(x : RawValue, y : RawValue) -> Bool

    RawValue::to_double

    fn RawValue::to_double(self : RawValue) -> Double

    RawValue::to_repr

    Signal

    pub(all) struct Signal {
    name : String
    start_bit : Int
    bit_length : Int
    byte_order : ByteOrder
    value_kind : ValueKind
    value_type : SignalValueType
    factor : Double
    offset : Double
    minimum : Double
    maximum : Double
    unit : String
    receivers : Array[String]
    multiplex : MultiplexRole
    } derive(Eq,
    Debug
    )

    Signal::decode

    fn Signal::decode(self : Signal, payload : BytesView) -> Result[Double, DecodeError]

    Decode a DBC signal and apply its factor and offset.

    Signal::decode_raw

    fn Signal::decode_raw(self : Signal, payload : BytesView) -> Result[RawValue, DecodeError]

    Decode the raw bits of an Intel- or Motorola-ordered DBC signal.

    Signal::encode

    fn Signal::encode(self : Signal, payload : BytesView, physical : Double) -> Result[Bytes, EncodeError]

    Convert a physical value to the nearest raw integer and insert it into a copy of a CAN payload.

    Signal::encode_raw

    fn Signal::encode_raw(self : Signal, payload : BytesView, value : RawValue) -> Result[Bytes, EncodeError]

    Insert a raw signal value into a copy of a CAN payload.

    Signal::equal

    fn Signal::equal(Signal, Signal) -> Bool

    Signal::not_equal

    fn Signal::not_equal(x : Signal, y : Signal) -> Bool

    Signal::to_repr

    SignalAssignment

    pub(all) struct SignalAssignment {
    name : String
    physical : Double
    } derive(Eq,
    Debug
    )

    A physical value assigned to a signal when building a complete CAN frame.

    SignalAssignment::equal

    SignalAssignment::not_equal

    fn SignalAssignment::not_equal(x : SignalAssignment, y : SignalAssignment) -> Bool

    SignalGroup

    pub(all) struct SignalGroup {
    message_id : UInt
    name : String
    repetition : Int
    signals : Array[String]
    } derive(Eq,
    Debug
    )

    A named DBC signal group. Groups are descriptive metadata used by editors, diagnostics, and generated integrations; they do not alter CAN bit layout.

    SignalGroup::equal

    fn SignalGroup::equal(SignalGroup, SignalGroup) -> Bool

    SignalGroup::not_equal

    fn SignalGroup::not_equal(x : SignalGroup, y : SignalGroup) -> Bool

    SignalGroupSourceLocation

    pub(all) struct SignalGroupSourceLocation {
    message_id : UInt
    name : String
    declaration : SourceSpan
    } derive(Eq,
    Debug
    )

    SignalGroupSourceLocation::equal

    SignalGroupSourceLocation::not_equal

    SignalSourceLocation

    pub(all) struct SignalSourceLocation {
    message_id : UInt
    signal_name : String
    declaration : SourceSpan
    } derive(Eq,
    Debug
    )

    SignalSourceLocation::equal

    SignalSourceLocation::not_equal

    SignalValueType

    pub(all) enum SignalValueType {
    Integer
    Float32
    Float64
    } derive(Eq,
    Debug
    )

    Physical storage selected by an optional SIG_VALTYPE_ declaration.

    SignalValueType::equal

    SignalValueType::not_equal

    fn SignalValueType::not_equal(x : SignalValueType, y : SignalValueType) -> Bool

    SourceParseResult

    pub(all) struct SourceParseResult {
    database : Database
    diagnostics : Array[Diagnostic]
    source_map : DbcSourceMap
    } derive(Eq,
    Debug
    )

    SourceParseResult::analyze_frame_layout

    fn SourceParseResult::analyze_frame_layout(self : SourceParseResult, message_id : UInt) -> Result[FrameLayoutAnalysis, FrameLayoutError]

    Analyze a parsed message and attach its original DBC declaration ranges.

    SourceParseResult::diff_with_locations

    Compare parsed DBCs and attach the old and new declaration ranges to each change. Global metadata has no declaration mapping and returns None.

    SourceParseResult::equal

    SourceParseResult::is_valid

    fn SourceParseResult::is_valid(self : SourceParseResult) -> Bool

    SourceParseResult::locate_validation_issues

    fn SourceParseResult::locate_validation_issues(self : SourceParseResult) -> Array[LocatedValidationIssue]

    Validate the parsed model and attach declaration locations where available. Overlap issues point to the later signal; comment issues without declaration locations retain None rather than inventing a source position.

    SourceParseResult::not_equal

    fn SourceParseResult::not_equal(x : SourceParseResult, y : SourceParseResult) -> Bool

    SourceSpan

    pub(all) struct SourceSpan {
    start_line : Int
    start_column : Int
    end_line : Int
    end_column : Int
    } derive(Eq,
    Debug
    )

    A half-open source range. Lines and columns are one-based; the end position points immediately after the declaration.

    SourceSpan::equal

    fn SourceSpan::equal(SourceSpan, SourceSpan) -> Bool

    SourceSpan::not_equal

    fn SourceSpan::not_equal(x : SourceSpan, y : SourceSpan) -> Bool

    TraceDecodeResult

    pub(all) struct TraceDecodeResult {
    frames : Array[DecodedTraceFrame]
    diagnostics : Array[TraceDiagnostic]
    } derive(Eq,
    Debug
    )

    TraceDecodeResult::equal

    TraceDecodeResult::is_valid

    fn TraceDecodeResult::is_valid(self : TraceDecodeResult) -> Bool

    TraceDecodeResult::not_equal

    fn TraceDecodeResult::not_equal(x : TraceDecodeResult, y : TraceDecodeResult) -> Bool

    TraceDecodeResult::summary

    TraceDecodeResult::to_csv

    fn TraceDecodeResult::to_csv(self : TraceDecodeResult) -> Result[String, CanLogTextError]

    Export successfully decoded trace signals as RFC 4180-style CSV rows. Text fields are always quoted and embedded quotes are doubled.

    TraceDiagnostic

    pub(all) struct TraceDiagnostic {
    line : Int
    text : String
    error : TraceError
    } derive(Eq,
    Debug
    )

    TraceDiagnostic::equal

    TraceDiagnostic::not_equal

    fn TraceDiagnostic::not_equal(x : TraceDiagnostic, y : TraceDiagnostic) -> Bool

    TraceError

    pub(all) enum TraceError {
    TraceFrameTextError(CanFrameTextError)
    TraceCanLogTextError(CanLogTextError)
    TraceFrameDecodeError(FrameDecodeError)
    } derive(Eq,
    Debug
    )

    TraceError::equal

    fn TraceError::equal(TraceError, TraceError) -> Bool

    TraceError::not_equal

    fn TraceError::not_equal(x : TraceError, y : TraceError) -> Bool

    TraceSummary

    pub(all) struct TraceSummary {
    records : Int
    decoded_frames : Int
    decoded_signals : Int
    unknown_frames : Int
    malformed_records : Int
    short_payload_frames : Int
    failed_frames : Int
    } derive(Eq,
    Debug
    )

    Counts accepted records and the reasons other records could not be decoded. Unknown identifiers are kept separate because partial DBC coverage is normal.

    TraceSummary::equal

    TraceSummary::not_equal

    fn TraceSummary::not_equal(x : TraceSummary, y : TraceSummary) -> Bool

    ValidationIssue

    pub(all) enum ValidationIssue {
    InvalidMessageIdentifierIssue(UInt)
    DuplicateMessageIdIssue(UInt)
    InvalidPayloadSizeIssue(UInt, Int)
    DuplicateSignalNameIssue(UInt, String)
    InvalidSignalLayoutIssue(UInt, String, Int, Int)
    InvalidSignalValueTypeIssue(UInt, String, SignalValueType, Int)
    FloatingMultiplexerIssue(UInt, String, SignalValueType)
    SignalOutsidePayloadIssue(UInt, String)
    InvalidScaleIssue(UInt, String, Double, Double)
    InvalidPhysicalRangeIssue(UInt, String, Double, Double)
    MultipleMultiplexersIssue(UInt)
    MissingMultiplexerIssue(UInt, String)
    MultiplexSelectorOutOfRangeIssue(UInt, String, Int)
    InvalidMultiplexRangeIssue(UInt, String, Int, Int)
    UnknownMultiplexSelectorIssue(UInt, String, String)
    OverlappingSignalsIssue(UInt, String, String)
    DuplicateCommentIssue(DbcCommentTarget)
    UnknownCommentNodeIssue(String)
    UnknownCommentMessageIssue(UInt)
    UnknownCommentSignalIssue(UInt, String)
    UnknownCommentEnvironmentIssue(String)
    DuplicateMessageTransmitterIssue(UInt, String)
    DuplicateAttributeDefinitionIssue(String)
    DuplicateAttributeDefaultIssue(String)
    DuplicateAttributeAssignmentIssue(String, DbcAttributeTarget)
    UnknownAttributeDefinitionIssue(String)
    InvalidAttributeTargetIssue(String, DbcAttributeTarget)
    AttributeScopeMismatchIssue(String, DbcAttributeTarget)
    InvalidAttributeValueIssue(String)
    DuplicateSignalGroupIssue(UInt, String)
    InvalidSignalGroupIssue(UInt, String)
    UnknownSignalGroupMessageIssue(UInt, String)
    UnknownSignalGroupMemberIssue(UInt, String, String)
    DuplicateGlobalValueTableIssue(String)
    InvalidGlobalValueTableIssue(String)
    DuplicateEnvironmentVariableIssue(String)
    InvalidEnvironmentVariableIssue(String)
    } derive(Eq,
    Debug
    )

    ValidationIssue::description

    fn ValidationIssue::description(self : ValidationIssue) -> String

    Human-readable explanation of a semantic DBC validation issue.

    ValidationIssue::equal

    ValidationIssue::not_equal

    fn ValidationIssue::not_equal(x : ValidationIssue, y : ValidationIssue) -> Bool

    ValueDescription

    pub(all) struct ValueDescription {
    value : Int64
    label : String
    } derive(Eq,
    Debug
    )

    ValueDescription::equal

    ValueDescription::not_equal

    fn ValueDescription::not_equal(x : ValueDescription, y : ValueDescription) -> Bool

    ValueKind

    pub(all) enum ValueKind {
    Unsigned
    Signed
    } derive(Eq,
    Debug
    )

    ValueKind::equal

    fn ValueKind::equal(ValueKind, ValueKind) -> Bool

    ValueKind::not_equal

    fn ValueKind::not_equal(x : ValueKind, y : ValueKind) -> Bool

    ValueTable

    pub(all) struct ValueTable {
    message_id : UInt
    signal_name : String
    entries : Array[ValueDescription]
    } derive(Eq,
    Debug
    )

    ValueTable::equal

    fn ValueTable::equal(ValueTable, ValueTable) -> Bool

    ValueTable::find_label

    fn ValueTable::find_label(self : ValueTable, value : Int64) -> String?

    ValueTable::not_equal

    fn ValueTable::not_equal(x : ValueTable, y : ValueTable) -> Bool

    ValueTableSourceLocation

    pub(all) struct ValueTableSourceLocation {
    message_id : UInt
    signal_name : String
    declaration : SourceSpan
    } derive(Eq,
    Debug
    )

    ValueTableSourceLocation::equal

    ValueTableSourceLocation::not_equal

    parse

    fn parse(source : StringView) -> ParseResult

    Parse the semantic DBC model while retaining all recoverable errors as source-line diagnostics. Use parse_with_source_map when declaration ranges are needed for editors or visualizations.

    parse_can_frame

    fn parse_can_frame(text : StringView) -> Result[CanFrame, CanFrameTextError]

    Parse the compact SocketCAN representation ID#DATA. One to three ID digits denote a standard frame; four to eight denote an extended frame. The payload may be empty and may contain up to 64 bytes for CAN FD.

    parse_can_log_record

    fn parse_can_log_record(text : StringView) -> Result[CanLogRecord, CanLogTextError]

    Parse compact SocketCAN text, INTERFACE ID#DATA, or the common candump form (TIMESTAMP) INTERFACE ID#DATA. CAN FD uses ID##FLAGS+DATA with one hexadecimal flags digit. Timestamp text is preserved without losing precision.

    parse_with_source_map

    fn parse_with_source_map(source : StringView) -> SourceParseResult

    Parse the core declarations of a DBC document while retaining all recoverable errors and declaration locations.

    run_cli

    fn run_cli(mode : CliMode, path : String, source : StringView) -> CliOutput

    Run a deterministic CLI operation against already-loaded DBC text. Keeping file access outside this function makes command behavior portable and easy to test independently from the native executable.

    run_decode_cli

    fn run_decode_cli(dbc_path : String, dbc_source : StringView, trace_path : String, trace_source : StringView) -> CliOutput

    Parse and validate a DBC database, decode a SocketCAN or candump trace, and return decoded signal rows as CSV. Valid records are retained when another trace line is malformed; diagnostics and a non-zero exit code report the partial failure.

    run_diff_cli

    fn run_diff_cli(before_path : String, before_source : StringView, after_path : String, after_source : StringView) -> CliOutput

    Parse and validate two DBC sources, then render their compatibility report as Markdown. Breaking changes use exit code 3 so CI can distinguish an incompatible database revision from malformed input.

    run_encode_cli

    fn run_encode_cli(path : String, source : StringView, identifier : String, assignment_texts : Array[String]) -> CliOutput

    Parse and validate a DBC source, encode named physical values into a CAN frame, and render canonical SocketCAN text. The CAN identifier uses one to three hexadecimal digits for a standard frame and four to eight for an extended frame.

    run_format_cli

    fn run_format_cli(path : String, source : StringView, check_only : Bool) -> CliOutput

    Parse and validate a DBC source, then emit the deterministic representation used by Database::to_dbc. Check mode produces no standard output and uses exit code 4 when the input differs from that representation. Unsupported declarations are rejected so formatting never silently removes source data.

    run_generate_cli

    fn run_generate_cli(path : String, source : StringView) -> CliOutput

    Parse and validate a DBC source, then generate standalone MoonBit constants for build-time integration.

    run_generate_codecs_cli

    fn run_generate_codecs_cli(path : String, source : StringView) -> CliOutput

    Generate named signal encode/decode functions from a valid DBC source.

    run_summary_cli

    fn run_summary_cli(dbc_path : String, dbc_source : StringView, trace_path : String, trace_source : StringView) -> CliOutput

    Summarize how much of a trace a DBC covers without emitting one diagnostic per unknown frame. Unknown identifiers are informational; malformed records and failed decodes still make the command fail.