a bare-bones limbo server in rust (mirror of https://github.com/xoogware/crawlspace)
at protocol-breakout 245 lines 5.5 kB view raw
1/* 2 * Copyright (c) 2024 Andrew Brower. 3 * This file is part of Crawlspace. 4 * 5 * Crawlspace is free software: you can redistribute it and/or 6 * modify it under the terms of the GNU Affero General Public 7 * License as published by the Free Software Foundation, either 8 * version 3 of the License, or (at your option) any later version. 9 * 10 * Crawlspace is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Affero General Public License for more details. 14 * 15 * You should have received a copy of the GNU Affero General Public 16 * License along with Crawlspace. If not, see 17 * <https://www.gnu.org/licenses/>. 18 */ 19 20use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; 21use uuid::Uuid; 22 23use crate::{ 24 ErrorKind::{self, InvalidData}, 25 Read, Write, 26}; 27 28impl Read for bool { 29 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> { 30 Ok(match r.read_u8()? { 31 0x01 => true, 32 0x00 => false, 33 v => { 34 return Err(InvalidData(format!( 35 "Expected 0x01 or 0x00 for bool, got {v}" 36 ))); 37 } 38 }) 39 } 40} 41 42impl Write for bool { 43 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 44 let v = match self { 45 true => 0x01, 46 false => 0x00, 47 }; 48 49 Ok(w.write_all(&[v])?) 50 } 51} 52 53impl Read for i8 { 54 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> { 55 Ok(r.read_i8()?) 56 } 57} 58 59impl Write for i8 { 60 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 61 Ok(w.write_i8(*self)?) 62 } 63} 64 65impl Read for u8 { 66 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 67 where 68 Self: Sized, 69 { 70 Ok(r.read_u8()?) 71 } 72} 73 74impl Write for u8 { 75 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 76 Ok(w.write_u8(*self)?) 77 } 78} 79 80impl Read for i16 { 81 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 82 where 83 Self: Sized, 84 { 85 Ok(r.read_i16::<BigEndian>()?) 86 } 87} 88 89impl Write for i16 { 90 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 91 Ok(w.write_i16::<BigEndian>(*self)?) 92 } 93} 94 95impl Read for u16 { 96 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 97 where 98 Self: Sized, 99 { 100 Ok(r.read_u16::<BigEndian>()?) 101 } 102} 103 104impl Read for i32 { 105 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 106 where 107 Self: Sized, 108 { 109 Ok(r.read_i32::<BigEndian>()?) 110 } 111} 112 113impl Write for i32 { 114 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 115 Ok(w.write_i32::<BigEndian>(*self)?) 116 } 117} 118 119impl Read for i64 { 120 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 121 where 122 Self: Sized, 123 { 124 Ok(r.read_i64::<BigEndian>()?) 125 } 126} 127 128impl Write for i64 { 129 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 130 Ok(w.write_i64::<BigEndian>(*self)?) 131 } 132} 133 134impl Read for u64 { 135 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 136 where 137 Self: Sized, 138 { 139 Ok(r.read_u64::<BigEndian>()?) 140 } 141} 142 143impl Write for u64 { 144 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 145 Ok(w.write_u64::<BigEndian>(*self)?) 146 } 147} 148 149impl Read for u128 { 150 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 151 where 152 Self: Sized, 153 { 154 Ok(r.read_u128::<BigEndian>()?) 155 } 156} 157 158impl Write for u128 { 159 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 160 Ok(w.write_u128::<BigEndian>(*self)?) 161 } 162} 163 164impl Read for f32 { 165 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 166 where 167 Self: Sized, 168 { 169 Ok(r.read_f32::<BigEndian>()?) 170 } 171} 172 173impl Write for f32 { 174 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 175 Ok(w.write_f32::<BigEndian>(*self)?) 176 } 177} 178 179impl Read for f64 { 180 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> 181 where 182 Self: Sized, 183 { 184 Ok(r.read_f64::<BigEndian>()?) 185 } 186} 187 188impl Write for f64 { 189 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 190 Ok(w.write_f64::<BigEndian>(*self)?) 191 } 192} 193 194impl Write for Uuid { 195 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 196 self.as_u128().write(w) 197 } 198} 199 200impl Read for Uuid { 201 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> { 202 Ok(Uuid::from_u128(r.read_u128::<BigEndian>()?)) 203 } 204} 205 206impl<T> Write for Option<T> 207where 208 T: Write, 209{ 210 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 211 match self { 212 None => Ok(()), 213 Some(v) => v.write(w), 214 } 215 } 216} 217 218impl<T> Write for Vec<T> 219where 220 T: Write, 221{ 222 fn write(&self, w: &mut impl std::io::Write) -> Result<(), ErrorKind> { 223 for item in self { 224 item.write(w)?; 225 } 226 227 Ok(()) 228 } 229} 230 231impl<T> Read for Vec<T> 232where 233 T: Read, 234{ 235 fn read(r: &mut impl std::io::Read) -> Result<Self, ErrorKind> { 236 let times = r.read_i32::<BigEndian>()?; 237 let mut o = Vec::new(); 238 239 for _ in 0..times { 240 o.push(T::read(r)?) 241 } 242 243 Ok(o) 244 } 245}