1#![cfg_attr(not(feature = "std"), no_std)]
29
30#[cfg(feature = "alloc")]
31extern crate alloc;
32
33#[cfg(feature = "std")]
34extern crate std as alloc;
35
36mod verb;
37mod frame;
38mod payload;
39mod address;
40mod error;
41mod auth;
42
43pub use verb::Verb;
44pub use frame::{Frame, FrameBuilder};
45pub use payload::{Payload, PayloadEncoder, PayloadDecoder};
46pub use address::{Address, AddressString, HostCache};
47pub use error::{ProtocolError, ProtocolResult};
48pub use auth::{AuthLevel, AuthBlock, SecurityContext, SessionId, Signature};
49pub use auth::{is_protected_path, path_auth_level, PROTECTED_PATHS};
50
51pub const VERSION: u8 = 1;
53
54pub const END: u8 = 0x00;
56
57pub const ESC: u8 = 0x1B;
59
60pub const MAX_PAYLOAD_LEN: usize = 65535;
62
63pub const MAX_FRAME_SIZE: usize = MAX_PAYLOAD_LEN + 4;
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn test_ping_frame() {
72 let frame = Frame::new(Verb::Ping, Payload::empty());
74 let encoded = frame.encode();
75 assert_eq!(encoded, vec![0x05, 0x00]);
76 }
77
78 #[test]
79 fn test_scan_frame() {
80 let mut payload = Payload::new();
82 payload.push_str("/home/hue");
83 payload.push_byte(3); let frame = Frame::new(Verb::Scan, payload);
86 let encoded = frame.encode();
87
88 assert_eq!(encoded[0], 0x01); assert_eq!(encoded[encoded.len() - 1], 0x00); }
92
93 #[test]
94 fn test_escape_sequence() {
95 let mut payload = Payload::new();
97 payload.push_byte(0x00); payload.push_byte(0x1B); payload.push_byte(0x42); let encoded = payload.encode();
102 assert_eq!(encoded, vec![0x1B, 0x00, 0x1B, 0x1B, 0x42]);
103 }
104
105 #[test]
106 fn test_roundtrip() {
107 let original = Frame::new(Verb::Search, Payload::from_string("*.rs"));
108 let encoded = original.encode();
109 let decoded = Frame::decode(&encoded).unwrap();
110
111 assert_eq!(decoded.verb(), original.verb());
112 assert_eq!(decoded.payload().as_bytes(), original.payload().as_bytes());
113 }
114}