cleverdog/protocol/
scan.rs1use core::{convert::TryFrom, str};
2use std::net::SocketAddr;
3
4use crate::{mac::MacAddr, protocol::version::Version};
5
6#[derive(Debug, Clone, Copy)]
7pub struct ScanInfo {
8 mac: MacAddr,
10 version: Version,
12}
13
14impl TryFrom<&[u8]> for ScanInfo {
15 type Error = &'static str;
16
17 fn try_from(v: &[u8]) -> Result<Self, Self::Error> {
18 let mut it = v.split(|&ch| ch == b'\0');
19
20 let mac = match it.next() {
21 Some(mac) => match str::from_utf8(mac.into()) {
22 Ok(mac) => match MacAddr::from_str(mac) {
23 Ok(mac) => mac,
24 Err(..) => return Err("MAC address is invalid"),
25 },
26 Err(..) => return Err("MAC address contains invalid UTF-8 sequence"),
27 },
28 None => return Err("missing MAC address"),
29 };
30
31 let version = match it.next() {
32 Some(version) => match str::from_utf8(version.into()) {
33 Ok(version) => match Version::from_str(version) {
34 Ok(version) => version,
35 Err(..) => return Err("version is invalid"),
36 },
37 Err(..) => return Err("version contains invalid UTF-8 sequence"),
38 },
39 None => return Err("missing version"),
40 };
41
42 let v = Self { mac, version };
43
44 Ok(v)
45 }
46}
47
48#[derive(Debug, Clone, Copy)]
49pub struct LookupInfo {
50 addr: SocketAddr,
52 cid: [u8; 16],
54 info: ScanInfo,
56}
57
58impl LookupInfo {
59 pub fn new(addr: SocketAddr, cid: [u8; 16], info: ScanInfo) -> Self {
60 Self { addr, cid, info }
61 }
62
63 #[inline]
65 pub fn addr(&self) -> SocketAddr {
66 self.addr
67 }
68
69 #[inline]
71 pub fn cid(&self) -> &[u8] {
72 &self.cid[..]
73 }
74
75 #[inline]
77 pub fn mac(&self) -> &MacAddr {
78 &self.info.mac
79 }
80
81 #[inline]
83 pub fn version(&self) -> &Version {
84 &self.info.version
85 }
86}