Skip to main content

twine_codec/dataset/
network_key.rs

1// Copyright (c) 2025 Jake Swensen
2// SPDX-License-Identifier: MPL-2.0
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8#[cfg(any(test, feature = "alloc"))]
9use alloc::vec::Vec;
10
11use core::num::ParseIntError;
12use core::str::FromStr;
13
14use twine_rs_macros::Tlv;
15
16const NETWORK_KEY_SIZE: usize = 16;
17
18/// A Thread Network Key
19#[derive(Copy, Clone, Debug, Eq, PartialEq, Tlv)]
20#[tlv(tlv_type = 0x05, tlv_length = 16, derive_inner)]
21pub struct NetworkKey([u8; NETWORK_KEY_SIZE]);
22
23impl NetworkKey {
24    pub fn random() -> Self {
25        let mut bytes = [0u8; NETWORK_KEY_SIZE];
26        crate::fill_random_bytes(&mut bytes);
27        Self(bytes)
28    }
29}
30
31impl core::fmt::Display for NetworkKey {
32    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33        for byte in &self.0 {
34            write!(f, "{:02x}", byte)?;
35        }
36
37        Ok(())
38    }
39}
40
41#[cfg(any(test, feature = "alloc"))]
42impl From<NetworkKey> for Vec<u8> {
43    fn from(value: NetworkKey) -> Self {
44        value.0.to_vec()
45    }
46}
47
48impl From<u128> for NetworkKey {
49    fn from(key: u128) -> Self {
50        Self(key.to_be_bytes())
51    }
52}
53
54impl AsRef<[u8]> for NetworkKey {
55    fn as_ref(&self) -> &[u8] {
56        &self.0
57    }
58}
59
60impl AsMut<[u8]> for NetworkKey {
61    fn as_mut(&mut self) -> &mut [u8] {
62        &mut self.0
63    }
64}
65
66impl FromStr for NetworkKey {
67    type Err = ParseIntError;
68
69    fn from_str(s: &str) -> Result<Self, Self::Err> {
70        let key = u128::from_str_radix(s, 16)?;
71        Ok(Self::from(key))
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78    use crate::std::borrow::ToOwned;
79    extern crate alloc;
80
81    const EXPECTED_KEY_STR: &str = "0123456789abcdef0123456789abcdef";
82    const EXPECTED_KEY_U128: u128 = 0x0123_4567_89ab_cdef_0123_4567_89ab_cdef;
83    const EXPECTED_KEY_BYTES: [u8; NETWORK_KEY_SIZE] = [
84        0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd,
85        0xef,
86    ];
87
88    #[test]
89    fn success_from_str() {
90        let key =
91            NetworkKey::from_str(EXPECTED_KEY_STR).expect("Failed to parse network key string");
92        assert_eq!(key.0, EXPECTED_KEY_BYTES);
93    }
94
95    #[test]
96    fn fail_from_str() {
97        let key = NetworkKey::from_str("not a valid network key string");
98        assert!(key.is_err());
99
100        let too_long = EXPECTED_KEY_STR.to_owned() + "0927";
101        let key = NetworkKey::from_str(&too_long);
102        assert!(key.is_err());
103    }
104
105    #[test]
106    fn success_from_u128() {
107        let key = NetworkKey::from(EXPECTED_KEY_U128);
108        assert_eq!(key.0, EXPECTED_KEY_BYTES);
109    }
110
111    #[test]
112    fn success_as_ref() {
113        let key = NetworkKey::from(EXPECTED_KEY_U128);
114        let bytes = key.as_ref();
115        assert_eq!(bytes, &EXPECTED_KEY_BYTES);
116        assert_eq!(bytes.len(), NETWORK_KEY_SIZE);
117    }
118
119    #[test]
120    fn success_as_mut() {
121        let mut key = NetworkKey::from(EXPECTED_KEY_U128);
122        let bytes = key.as_mut();
123        assert_eq!(bytes, &EXPECTED_KEY_BYTES);
124        assert_eq!(bytes.len(), NETWORK_KEY_SIZE);
125    }
126}