1pub mod actions;
2pub mod settings;
3pub mod types;
4
5pub use actions::BussAction;
6pub use settings::BussSettings;
7pub use types::buss_flags;
8
9mod version {
11 pub const MAJOR: u8 = 1;
12 pub const MINOR: u8 = 0;
13}
14
15pub struct BussHeader {
17 pub magic_number: u32,
20 pub version_major: u8,
22 pub version_minor: u8,
24 pub action: BussAction,
26 pub flags: u8,
28}
29
30pub trait ToBytes {
32 fn to_bytes(self) -> Vec<u8>;
34}
35
36pub trait FromBytes<T: Sized> {
38 fn from_bytes(bytes: T) -> Self;
40}
41
42impl BussHeader {
43 pub fn new() -> Self {
45 BussHeader {
46 magic_number: 0x00042069,
47 version_major: version::MAJOR,
48 version_minor: version::MINOR,
49 action: BussAction::Noop,
50 flags: 0,
51 }
52 }
53 pub fn set_action(&mut self, action: BussAction) {
55 self.action = action;
56 }
57}
58
59impl Default for BussHeader {
60 fn default() -> Self {
61 Self::new()
62 }
63}
64
65impl ToBytes for BussHeader {
66 fn to_bytes(self) -> Vec<u8> {
67 let mut bytes = Vec::new();
68 bytes.extend(self.magic_number.to_be_bytes());
69 bytes.push(self.version_major);
70 bytes.push(self.version_minor);
71 bytes.push(self.action as u8);
72 bytes.push(self.flags);
73 bytes
74 }
75}
76impl FromBytes<&[u8; 8]> for BussHeader {
77 fn from_bytes(bytes: &[u8; 8]) -> Self {
78 let magic_bytes = &bytes[0..4];
79 let magic_number = u32::from_be_bytes(magic_bytes.try_into().unwrap());
80 let version_major = bytes[4];
81 let version_minor = bytes[5];
82 let action_number = bytes[6];
83 let action: BussAction = action_number.try_into().unwrap();
84 let flags = bytes[7];
85
86 BussHeader {
87 magic_number,
88 version_major,
89 version_minor,
90 action,
91 flags,
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use std::{
99 fs::File,
100 io::{self, Write},
101 };
102
103 use crate::{
104 settings::{BodyLength, Host, Settings},
105 types::BussPath,
106 BussAction, BussHeader, ToBytes,
107 };
108
109 #[test]
110 fn skeleton() -> io::Result<()> {
111 let mut header = BussHeader::new();
112 header.set_action(BussAction::Read);
113 let content = "Hello from the rizzler!";
114
115 let mut settings = Settings::new();
116 settings.add(Box::new(BodyLength::new(content.len())));
117 settings.add(Box::new(Host::new("buss.rizz")));
118
119 let path = BussPath::new("/");
120
121 let mut file: File = File::create("test.bbp")?;
122 let _ = file.write(&header.to_bytes())?;
123 let _ = file.write(&path.to_bytes())?;
124 let _ = file.write(&settings.to_bytes())?;
125
126 let _ = file.write(content.as_bytes())?;
127
128 Ok(())
129 }
130}