1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// Copyright (c) 2024 Nathan H. Keough
//
// This work is dual-licensed under MIT OR Apache 2.0 (or any later version).
// You may choose between one of them if you use this work.
//
// For further detail, please refer to the individual licenses located at the root of this crate.
//! A rust crate for encoding or decoding various Controller Area Network (CAN) data types, including the SAE J1939 standard.
//!
//! ## Supported CAN Protocols
//! This crate provides decoding capabilities for Controller Area Network (CAN) protocols utilizing both 11-bit and 29-bit identifiers.
//! - **CAN 2.0 (Classical CAN)**: Commonly used in automotive applications and industrial automation.
//! - **SAE J1939**: Commonly used in heavy-duty trucks and buses.
//!
//! ## `no_std` Support
//! This crate supports `no_std`, meaning it can be used in resource-constrained environments like embedded systems and `IoT` devices, allowing for minimal memory usage without compromising functionality.
//!
//! To enable `no_std`, use the `--no-default-features` flag:
//! ```shell
//! $ cargo add can_types --no-default-features
//! ```
//!
//! ### `no_std` limitations:
//! - This mode does not support generating [`String`](alloc::string::String) or string slice hexadecimal representations of the provided data structures.
//!
//! # Examples
//! ## Hex to J1939 Identifier
//! ```rust
//! # use can_types::prelude::*;
//! # fn main() -> Result<(), anyhow::Error> {
//! let id_a = IdJ1939::try_from_hex("0CF00400")?;
//!
//! assert_eq!(3, id_a.priority());
//! assert_eq!(SourceAddr::Some(0), id_a.source_address());
//! assert_eq!(Some(Addr::PrimaryEngineController), id_a.source_address().lookup());
//! # Ok(())
//! # }
//! ```
//!
//! ## Decode J1939 PGN
//! ```rust
//! # use can_types::prelude::*;
//! # fn main() -> Result<(), anyhow::Error> {
//! let id_a = IdJ1939::try_from_hex("18FEF200")?;
//!
//! assert_eq!(CommunicationMode::Broadcast, id_a.pgn().communication_mode());
//! assert_eq!(GroupExtension::Some(242), id_a.pgn().group_extension());
//!
//! let id_b = IdJ1939::try_from_hex("0C00290B")?;
//!
//! // SA 11 = Brakes
//! assert_eq!(SourceAddr::Some(11), id_b.source_address());
//! assert_eq!(Some(Addr::Brakes), id_b.source_address().lookup());
//!
//! assert_eq!(PduFormat::Pdu1(0), id_b.pgn().pdu_format());
//! assert_eq!(CommunicationMode::P2P, id_b.pgn().communication_mode());
//! assert_eq!(GroupExtension::None, id_b.pgn().group_extension());
//!
//! // DA 41 = Retarder, Exhaust, Engine
//! assert_eq!(DestinationAddr::Some(41), id_b.pgn().destination_address());
//! assert_eq!(Some(Addr::RetarderExhaustEngine1), id_b.pgn().destination_address().lookup());
//! # Ok(())
//! # }
//! ```
if_alloc!