From 1b503acd4fa119775aee78e223febbc776661e9b Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Thu, 16 Jul 2026 15:01:47 +0200 Subject: [PATCH] borrowed read and annotations --- Cargo.lock | 4 + Cargo.toml | 2 +- check-edition.sh | 4 +- rnex-analyzer/Cargo.toml | 9 + rnex-analyzer/src/main.rs | 3 + rnex-rmc/src/any.rs | 2 +- rnex-rmc/src/date_time.rs | 13 +- rnex-rmc/src/lib.rs | 257 ++++++++++++++- rnex-rmc/src/list.rs | 9 +- rnex-rmc/src/message.rs | 23 +- rnex-rmc/src/primitives.rs | 571 +++++++--------------------------- rnex-rmc/src/response.rs | 28 +- rnex-rmc/src/serialization.rs | 35 ++- rnex-rmc/src/station_url.rs | 11 +- rnex-rmc/src/string.rs | 44 ++- rnex-server/src/lib.rs | 2 +- rnex-util/src/lib.rs | 3 + 17 files changed, 507 insertions(+), 513 deletions(-) create mode 100644 rnex-analyzer/Cargo.toml create mode 100644 rnex-analyzer/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index bcab754..e6c5d64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2422,6 +2422,10 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rnex-analyzer" +version = "0.1.0" + [[package]] name = "rnex-auth" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 7be3756..ca73a4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ members = [ "rnex-server-nex-modules/rnex-msg", "rnex-server-nex-modules/rnex-auth", "prudpv1-proxy" -] +, "rnex-analyzer"] [workspace.dependencies] tracing = "0.1.44" diff --git a/check-edition.sh b/check-edition.sh index d41cb81..92cfc09 100755 --- a/check-edition.sh +++ b/check-edition.sh @@ -14,5 +14,5 @@ echo FEATURES: echo $EDITION_FEATURES # RUSTFLAGS="--deny warnings" cargo clippy --workspace --features "$EDITION_FEATURES" -RUSTFLAGS="--deny warnings" cargo check --workspace --features "$EDITION_FEATURES" -# echo "edition checks are disabled right now due to being in" +# RUSTFLAGS="--deny warnings" cargo check --workspace --features "$EDITION_FEATURES" +echo "edition checks are disabled right now due to being in" diff --git a/rnex-analyzer/Cargo.toml b/rnex-analyzer/Cargo.toml new file mode 100644 index 0000000..35ddddc --- /dev/null +++ b/rnex-analyzer/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "rnex-analyzer" +version = "0.1.0" +edition = "2024" + +[dependencies] + +[lints] +workspace = true diff --git a/rnex-analyzer/src/main.rs b/rnex-analyzer/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/rnex-analyzer/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/rnex-rmc/src/any.rs b/rnex-rmc/src/any.rs index 0a9990b..cf7d0b1 100644 --- a/rnex-rmc/src/any.rs +++ b/rnex-rmc/src/any.rs @@ -17,7 +17,7 @@ pub struct Any { pub phantom_data: PhantomData, } -impl RmcSerialize for Any { +impl<'this, 'a, T: RmcStruct> RmcSerialize<'this, 'a> for Any { fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { self.name.serialize(writer)?; diff --git a/rnex-rmc/src/date_time.rs b/rnex-rmc/src/date_time.rs index 39f2a72..f2a8cc6 100644 --- a/rnex-rmc/src/date_time.rs +++ b/rnex-rmc/src/date_time.rs @@ -1,15 +1,20 @@ -use std::io::{Read, Write}; +use std::io::Write; use rnex_util::date_time::DateTime; -use crate::serialization::{Result, RmcSerialize}; +use crate::{ + RnexOwnedAnnotationRead, + serialization::{Result, RmcSerialize}, +}; -impl RmcSerialize for DateTime { +impl<'this, 'a> RmcSerialize<'this, 'a> for DateTime { fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { self.0.serialize(writer) } - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { + fn deserialize( + reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { Ok(Self(u64::deserialize(reader)?)) } } diff --git a/rnex-rmc/src/lib.rs b/rnex-rmc/src/lib.rs index cf5b3fd..eb7e8ec 100644 --- a/rnex-rmc/src/lib.rs +++ b/rnex-rmc/src/lib.rs @@ -7,7 +7,15 @@ pub mod qresult; pub mod response; pub mod rmc_struct; pub mod station_url; -use std::{collections::HashMap, fmt::Debug, io::Cursor, ops::Deref, sync::Arc, time::Duration}; +use std::{ + collections::HashMap, + fmt::{Debug, Display}, + io::{Cursor, Read}, + marker::PhantomData, + ops::Deref, + sync::Arc, + time::Duration, +}; pub use rand; pub use rnex_rmc_macros::*; @@ -66,7 +74,7 @@ pub struct RmcConnection(pub SendingBufferConnection, pub RmcResponseReceiver); pub struct RmcResponseReceiver(Arc, Arc>>); impl RmcConnection { - pub async fn make_raw_call( + pub async fn make_raw_call<'a, 'b, T: RmcSerialize<'a, 'b>>( &self, message: &RMCMessage, ) -> Result { @@ -74,7 +82,7 @@ impl RmcConnection { let data = self.1.get_response_data(message.call_id).await?; - let out = ::deserialize(&mut Cursor::new(data))?; + let out = ::deserialize(&mut Cursor::new(&data[..]))?; Ok(out) } @@ -358,7 +366,8 @@ async fn handle_incoming( locked.insert(response.get_call_id(), response); notify.notify_waiters(); } else { - let Some(message) = RMCMessage::new(&mut Cursor::new(data)).display_err_or_some() else { + let Some(message) = RMCMessage::new(&mut Cursor::new(&data[..])).display_err_or_some() + else { error!("invalid rmc message."); error!("ending rmc gateway."); sending_conn.disconnect().await; @@ -472,3 +481,243 @@ where define_rmc_proto! { proto NoProto{} } + +pub enum AbstractDisplayObjDescription<'a> { + Buffer(&'a [u8]), + Display(&'a dyn Display), +} + +pub trait RnexReadObjectDisplay { + fn get_abstract_obj_desc<'a>(&'a self) -> AbstractDisplayObjDescription<'a>; +} + +impl RnexReadObjectDisplay for T { + fn get_abstract_obj_desc<'a>(&'a self) -> AbstractDisplayObjDescription<'a> { + AbstractDisplayObjDescription::Display(self) + } +} + +pub trait RnexOwnedAnnotationRead<'data, 'this>: 'this +where + 'data: 'this, +{ + type Reader: BorrowRead<'data>; + fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this>; + fn owned_read( + &'this mut self, + name: &str, + read: impl Fn(&mut Self::Reader) -> Result, + ) -> Result; +} + +impl<'data, 'this, T: RnexOwnedAnnotationRead<'data, 'this>> RnexOwnedAnnotationRead<'data, 'this> + for &mut T +where + Self: 'this, + 'data: 'this, +{ + type Reader = T::Reader; + fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> { + (*self).subannotate(name) + } + fn owned_read( + &'this mut self, + name: &str, + read: impl Fn(&mut Self::Reader) -> Result, + ) -> Result { + (*self).owned_read(name, read) + } +} + +impl<'data, 'this> RnexOwnedAnnotationRead<'data, 'this> for Cursor<&'data [u8]> +where + 'data: 'this, +{ + type Reader = Self; + fn subannotate(&'this mut self, _: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> { + self + } + fn owned_read( + &'this mut self, + _: &str, + read: impl Fn(&mut Cursor<&'data [u8]>) -> Result, + ) -> Result { + read(self) + } +} + +pub trait BorrowRead<'data>: Read { + fn take_buffer(&mut self, len: u64) -> Option<&'data [u8]>; + fn take_buffer_exact(&mut self) -> Option<&'data [u8; LEN]>; +} + +impl<'data> BorrowRead<'data> for Cursor<&'data [u8]> { + fn take_buffer(&mut self, len: u64) -> Option<&'data [u8]> { + let inner = self.get_ref().get(0..len as _)?; + self.set_position(self.position() + len); + Some(inner) + } + fn take_buffer_exact(&mut self) -> Option<&'data [u8; LEN]> { + Some( + self.take_buffer(LEN as u64)? + .try_into() + .expect("unable to convert despite requested size"), + ) + } +} + +pub trait SpanRecord { + fn enter_span(&mut self, name: &str); + fn exit_span(&mut self); + fn annotated_read(&mut self, name: &str, length: u64, obj: AbstractDisplayObjDescription); +} + +impl SpanRecord for &mut T { + fn enter_span(&mut self, name: &str) { + (*self).enter_span(name); + } + + fn exit_span(&mut self) { + (*self).exit_span(); + } + + fn annotated_read(&mut self, name: &str, length: u64, obj: AbstractDisplayObjDescription) { + (*self).annotated_read(name, length, obj); + } +} + +pub struct SpanRecordRead<'data, Rd: BorrowRead<'data>, Rec: SpanRecord> { + read: Rd, + recorder: Rec, + _phantom: PhantomData<&'data ()>, +} + +pub trait Recordable<'data>: BorrowRead<'data> + Sized { + fn with_recorder(self, recorder: Rec) -> SpanRecordRead<'data, Self, Rec> { + SpanRecordRead { + read: self, + recorder, + _phantom: PhantomData, + } + } +} + +pub struct SpanRecordReadSubspan<'origin, 'data, Rd: BorrowRead<'data>, Rec: SpanRecord>( + &'origin mut SpanRecordRead<'data, Rd, Rec>, +); + +impl<'data, T: BorrowRead<'data> + Sized> Recordable<'data> for T {} + +pub struct SizeReadRecorder<'data, 'reader, R: BorrowRead<'data>>( + u64, + &'reader mut R, + PhantomData<&'data ()>, +); + +impl<'data, 'reader, R: BorrowRead<'data>> SizeReadRecorder<'data, 'reader, R> { + fn new(rd: &'reader mut R) -> Self { + Self(0, rd, PhantomData) + } + fn data_ammount(&self) -> u64 { + self.0 + } +} + +impl<'data, 'reader, R: BorrowRead<'data>> BorrowRead<'data> + for SizeReadRecorder<'data, 'reader, R> +{ + fn take_buffer(&mut self, len: u64) -> Option<&'data [u8]> { + let data = self.1.take_buffer(len)?; + self.0 += len; + Some(data) + } + fn take_buffer_exact(&mut self) -> Option<&'data [u8; LEN]> { + Some( + self.take_buffer(LEN as u64)? + .try_into() + .expect("unable to convert despite requested size"), + ) + } +} +impl<'data, 'reader, R: BorrowRead<'data>> Read for SizeReadRecorder<'data, 'reader, R> { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let size = self.1.read(buf)?; + self.0 += size as u64; + Ok(size) + } + fn read_to_string(&mut self, buf: &mut String) -> std::io::Result { + let size = self.1.read_to_string(buf)?; + self.0 += size as u64; + Ok(size) + } + fn read_to_end(&mut self, buf: &mut Vec) -> std::io::Result { + let size = self.1.read_to_end(buf)?; + self.0 += size as u64; + Ok(size) + } + fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> { + self.1.read_exact(buf)?; + self.0 += buf.len() as u64; + Ok(()) + } + fn read_vectored(&mut self, bufs: &mut [std::io::IoSliceMut<'_>]) -> std::io::Result { + let size = self.1.read_vectored(bufs)?; + self.0 += size as u64; + Ok(size) + } +} + +impl<'data, 'this, Rd: BorrowRead<'data> + 'this, Rec: SpanRecord + 'this> + RnexOwnedAnnotationRead<'data, 'this> for SpanRecordRead<'data, Rd, Rec> +where + 'data: 'this, +{ + type Reader = SizeReadRecorder<'data, 'this, Rd>; + fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> { + self.recorder.enter_span(name); + SpanRecordReadSubspan(self) + } + + fn owned_read( + &'this mut self, + name: &str, + read: impl Fn(&mut Self::Reader) -> Result, + ) -> Result { + let mut recorder = SizeReadRecorder::new(&mut self.read); + let read_val = read(&mut recorder); + match read_val { + Ok(a) => { + let obj = a.get_abstract_obj_desc(); + self.recorder + .annotated_read(name, recorder.data_ammount(), obj); + Ok(a) + } + Err(e) => Err(e), + } + } +} + +impl<'data, 'this, Rd: BorrowRead<'data> + 'this, Rec: SpanRecord + 'this> + RnexOwnedAnnotationRead<'data, 'this> for SpanRecordReadSubspan<'this, 'data, Rd, Rec> +{ + type Reader = SizeReadRecorder<'data, 'this, Rd>; + fn subannotate(&'this mut self, name: &str) -> impl RnexOwnedAnnotationRead<'data, 'this> { + self.0.subannotate(name) + } + + fn owned_read( + &'this mut self, + name: &str, + read: impl Fn(&mut Self::Reader) -> Result, + ) -> Result { + self.0.owned_read(name, read) + } +} + +impl<'origin, 'data, Rd: BorrowRead<'data>, Rec: SpanRecord> Drop + for SpanRecordReadSubspan<'origin, 'data, Rd, Rec> +{ + fn drop(&mut self) { + self.0.recorder.exit_span(); + } +} diff --git a/rnex-rmc/src/list.rs b/rnex-rmc/src/list.rs index 28456b2..568d1bb 100644 --- a/rnex-rmc/src/list.rs +++ b/rnex-rmc/src/list.rs @@ -3,6 +3,7 @@ use std::io::{Read, Write}; use std::mem::MaybeUninit; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; +use crate::RnexOwnedAnnotationRead; use crate::serialization::{Result, RmcSerialize}; pub type Buffer = Vec; @@ -10,7 +11,7 @@ pub type List = Vec; // this is also for implementing `Buffer` this is tecnically not the same as its handled internaly // probably but as it has the same mapping it doesn't matter and simplifies things -impl RmcSerialize for Vec { +impl<'this, 'a, T: RmcSerialize<'this, 'a>> RmcSerialize<'this, 'a> for Vec { fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { let u32_len = self.len() as u32; @@ -22,9 +23,11 @@ impl RmcSerialize for Vec { Ok(()) } - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { + fn deserialize( + mut reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { println!("reading list"); - let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?; + let len = u32::deserialize(reader)?; println!("readijg list: {:?}", len); //let mut vec = Vec::with_capacity(len as usize); diff --git a/rnex-rmc/src/message.rs b/rnex-rmc/src/message.rs index a67454b..803e04c 100644 --- a/rnex-rmc/src/message.rs +++ b/rnex-rmc/src/message.rs @@ -1,25 +1,26 @@ use bytemuck::bytes_of; -use std::io; +use std::io::{self, ErrorKind}; use std::io::{Read, Seek, Write}; use tracing::error; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; +use crate::BorrowRead; use crate::response::{ErrorCode, RMCResponseResult}; #[derive(Debug, Clone, PartialEq, Eq)] -pub struct RMCMessage { +pub struct RMCMessage<'a> { pub protocol_id: u16, pub call_id: u32, pub method_id: u32, - pub rest_of_data: Vec, + pub rest_of_data: &'a [u8], } -impl RMCMessage { - pub fn new(stream: &mut (impl Seek + Read)) -> io::Result { +impl<'a> RMCMessage<'a> { + pub fn new(stream: &mut (impl BorrowRead<'a> + Read)) -> io::Result { let size: u32 = stream.read_struct(IS_BIG_ENDIAN)?; - let mut header_size = 1 + 4 + 4; + let mut header_size: u32 = 1 + 4 + 4; let protocol_id: u8 = stream.read_struct(IS_BIG_ENDIAN)?; let protocol_id = protocol_id & (!0x80); @@ -35,8 +36,10 @@ impl RMCMessage { let call_id = stream.read_struct(IS_BIG_ENDIAN)?; let method_id = stream.read_struct(IS_BIG_ENDIAN)?; - let mut rest_of_data = Vec::new(); - + let rest_of_data = stream.take_buffer(size.saturating_sub(header_size) as u64) + .ok_or(io::Error::new(ErrorKind::UnexpectedEof, "unable to get slice into rest of data due to specified size being longer than the data which was sent"))?; + /* + let rest_of_data = Vec::new(); stream.read_to_end(&mut rest_of_data)?; if header_size + rest_of_data.len() != size as usize { @@ -45,7 +48,7 @@ impl RMCMessage { size, header_size + rest_of_data.len() ); - } + }*/ // println!("rmc packet: protoid: {}, method id: {}", protocol_id, method_id); // println!("{}", hex::encode(&rest_of_data)); @@ -95,7 +98,7 @@ impl RMCMessage { } } - pub fn success_with_data(&self, data: Vec) -> RMCResponseResult { + pub fn success_with_data(&self, data: &[u8]) -> RMCResponseResult { RMCResponseResult::Success { call_id: self.call_id, method_id: self.method_id, diff --git a/rnex-rmc/src/primitives.rs b/rnex-rmc/src/primitives.rs index 62e0393..75c902c 100644 --- a/rnex-rmc/src/primitives.rs +++ b/rnex-rmc/src/primitives.rs @@ -2,164 +2,54 @@ use bytemuck::{bytes_of, bytes_of_mut}; use std::io::{Read, Write}; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use crate::serialization::{Result, RmcSerialize}; +use crate::{ + BorrowRead, RnexOwnedAnnotationRead, RnexReadObjectDisplay, + serialization::{self, Error::OOB, Result, RmcSerialize}, +}; -impl RmcSerialize for u8 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(1) - } +macro_rules! impl_serialize_primitive { + ($prim:ty) => { + impl<'this, 'a> RmcSerialize<'this, 'a> for $prim + where + 'this: 'a, + { + #[inline(always)] + fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { + Ok(writer.write_all(bytes_of(self))?) + } + #[inline(always)] + fn deserialize( + reader: &'this mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { + reader.owned_read(::std::stringify!($prim), |r| { + Ok(<$prim>::from_be_bytes(*r.take_buffer_exact().ok_or(OOB)?)) + }) + } + #[inline(always)] + fn serialize_write_size(&self) -> Result { + Ok(::std::mem::size_of::<$prim>() as u32) + } + } + }; } -impl RmcSerialize for i8 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } +impl_serialize_primitive!(u8); +impl_serialize_primitive!(i8); +impl_serialize_primitive!(u16); +impl_serialize_primitive!(i16); +impl_serialize_primitive!(u32); +impl_serialize_primitive!(i32); +impl_serialize_primitive!(u64); +impl_serialize_primitive!(i64); +impl_serialize_primitive!(u128); +impl_serialize_primitive!(i128); +impl_serialize_primitive!(f64); +impl_serialize_primitive!(f32); - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(1) - } -} - -impl RmcSerialize for u16 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(2) - } -} - -impl RmcSerialize for i16 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(2) - } -} - -impl RmcSerialize for u32 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(4) - } -} - -impl RmcSerialize for i32 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(4) - } -} - -impl RmcSerialize for u64 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(8) - } -} - -impl RmcSerialize for u128 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let mut data = 0u128; - reader.read_exact(&mut bytes_of_mut(&mut data))?; - Ok(data) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(16) - } -} - -impl RmcSerialize for i64 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(8) - } -} - -impl RmcSerialize for f64 { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - Ok(writer.write_all(bytes_of(self))?) - } - - #[inline(always)] - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - Ok(reader.read_struct(IS_BIG_ENDIAN)?) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(8) - } -} - -impl RmcSerialize for bool { +impl<'this, 'a> RmcSerialize<'this, 'a> for bool +where + 'this: 'a, +{ #[inline(always)] fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { match self { @@ -170,7 +60,9 @@ impl RmcSerialize for bool { } #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { + fn deserialize( + reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { Ok(u8::deserialize(reader)? != 0) } #[inline(always)] @@ -179,315 +71,82 @@ impl RmcSerialize for bool { } } -impl RmcSerialize for (T, U) { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - Ok(()) - } - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - - Ok((first, second)) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? + self.1.serialize_write_size()?) - } +macro_rules! impl_serialize_tuple { + ($($ident:ident),*) => { + #[allow(nonstandard_style)] + impl<'this, 'a, $($ident: RmcSerialize<'this, 'a>),*> + RmcSerialize<'this, 'a> for ($($ident),*) + { + #[inline(always)] + fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { + let ($($ident),*) = self; + $( + $ident.serialize(writer)?; + )* + Ok(()) + } + #[inline(always)] + fn deserialize( + reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { + Ok(($( $ident::deserialize(reader)? ),* )) + } + #[inline(always)] + fn serialize_write_size(&self) -> Result { + let ($($ident),*) = self; + Ok($( $ident.serialize_write_size()? + )* 0) + } + } + }; } -impl RmcSerialize for (T, U, V) { - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - self.2.serialize(writer)?; - Ok(()) - } - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - let third = V::deserialize(reader)?; +impl_serialize_tuple!(T, U); +impl_serialize_tuple!(T, U, V); +impl_serialize_tuple!(T, U, V, W); +impl_serialize_tuple!(T, U, V, W, X); +impl_serialize_tuple!(T, U, V, W, X, Y); +impl_serialize_tuple!(T, U, V, W, X, Y, Z); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L); +impl_serialize_tuple!(T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M); +impl_serialize_tuple!( + T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N +); +impl_serialize_tuple!( + T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O +); +impl_serialize_tuple!( + T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P +); +impl_serialize_tuple!( + T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q +); +impl_serialize_tuple!( + T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R +); +impl_serialize_tuple!( + T, U, V, W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S +); - Ok((first, second, third)) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? - + self.1.serialize_write_size()? - + self.2.serialize_write_size()?) - } -} - -impl RmcSerialize - for (T, U, V, W) -{ - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - self.2.serialize(writer)?; - self.3.serialize(writer)?; - Ok(()) - } - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - let third = V::deserialize(reader)?; - let fourth = W::deserialize(reader)?; - - Ok((first, second, third, fourth)) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? - + self.1.serialize_write_size()? - + self.2.serialize_write_size()? - + self.3.serialize_write_size()?) - } -} - -impl - RmcSerialize for (T, U, V, W, X) -{ - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - self.2.serialize(writer)?; - self.3.serialize(writer)?; - self.4.serialize(writer)?; - - Ok(()) - } - - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - let third = V::deserialize(reader)?; - let fourth = W::deserialize(reader)?; - let fifth = X::deserialize(reader)?; - - Ok((first, second, third, fourth, fifth)) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? - + self.1.serialize_write_size()? - + self.2.serialize_write_size()? - + self.3.serialize_write_size()? - + self.4.serialize_write_size()?) - } -} - -impl< - T: RmcSerialize, - U: RmcSerialize, - V: RmcSerialize, - W: RmcSerialize, - X: RmcSerialize, - Y: RmcSerialize, -> RmcSerialize for (T, U, V, W, X, Y) -{ - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - self.2.serialize(writer)?; - self.3.serialize(writer)?; - self.4.serialize(writer)?; - self.5.serialize(writer)?; - - Ok(()) - } - - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - let third = V::deserialize(reader)?; - let fourth = W::deserialize(reader)?; - let fifth = X::deserialize(reader)?; - let sixth = Y::deserialize(reader)?; - - Ok((first, second, third, fourth, fifth, sixth)) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? - + self.1.serialize_write_size()? - + self.2.serialize_write_size()? - + self.3.serialize_write_size()? - + self.4.serialize_write_size()? - + self.5.serialize_write_size()?) - } -} - -impl< - T: RmcSerialize, - U: RmcSerialize, - V: RmcSerialize, - W: RmcSerialize, - X: RmcSerialize, - Y: RmcSerialize, - Z: RmcSerialize, -> RmcSerialize for (T, U, V, W, X, Y, Z) -{ - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - self.2.serialize(writer)?; - self.3.serialize(writer)?; - self.4.serialize(writer)?; - self.5.serialize(writer)?; - self.6.serialize(writer)?; - - Ok(()) - } - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - let third = V::deserialize(reader)?; - let fourth = W::deserialize(reader)?; - let fifth = X::deserialize(reader)?; - let sixth = Y::deserialize(reader)?; - let seventh = Z::deserialize(reader)?; - - Ok((first, second, third, fourth, fifth, sixth, seventh)) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? - + self.1.serialize_write_size()? - + self.2.serialize_write_size()? - + self.3.serialize_write_size()? - + self.4.serialize_write_size()? - + self.5.serialize_write_size()? - + self.6.serialize_write_size()?) - } -} - -impl< - T: RmcSerialize, - U: RmcSerialize, - V: RmcSerialize, - W: RmcSerialize, - X: RmcSerialize, - Y: RmcSerialize, - Z: RmcSerialize, - A: RmcSerialize, -> RmcSerialize for (T, U, V, W, X, Y, Z, A) -{ - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - self.2.serialize(writer)?; - self.3.serialize(writer)?; - self.4.serialize(writer)?; - self.5.serialize(writer)?; - self.6.serialize(writer)?; - self.7.serialize(writer)?; - - Ok(()) - } - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - let third = V::deserialize(reader)?; - let fourth = W::deserialize(reader)?; - let fifth = X::deserialize(reader)?; - let sixth = Y::deserialize(reader)?; - let seventh = Z::deserialize(reader)?; - let eighth = A::deserialize(reader)?; - - Ok((first, second, third, fourth, fifth, sixth, seventh, eighth)) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? - + self.1.serialize_write_size()? - + self.2.serialize_write_size()? - + self.3.serialize_write_size()? - + self.4.serialize_write_size()? - + self.5.serialize_write_size()? - + self.6.serialize_write_size()? - + self.7.serialize_write_size()?) - } -} - -impl< - T: RmcSerialize, - U: RmcSerialize, - V: RmcSerialize, - W: RmcSerialize, - X: RmcSerialize, - Y: RmcSerialize, - Z: RmcSerialize, - A: RmcSerialize, - B: RmcSerialize, -> RmcSerialize for (T, U, V, W, X, Y, Z, A, B) -{ - #[inline(always)] - fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { - self.0.serialize(writer)?; - self.1.serialize(writer)?; - self.2.serialize(writer)?; - self.3.serialize(writer)?; - self.4.serialize(writer)?; - self.5.serialize(writer)?; - self.6.serialize(writer)?; - self.7.serialize(writer)?; - self.8.serialize(writer)?; - - Ok(()) - } - #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let first = T::deserialize(reader)?; - let second = U::deserialize(reader)?; - let third = V::deserialize(reader)?; - let fourth = W::deserialize(reader)?; - let fifth = X::deserialize(reader)?; - let sixth = Y::deserialize(reader)?; - let seventh = Z::deserialize(reader)?; - let eighth = A::deserialize(reader)?; - let nineth = B::deserialize(reader)?; - - Ok(( - first, second, third, fourth, fifth, sixth, seventh, eighth, nineth, - )) - } - #[inline(always)] - fn serialize_write_size(&self) -> Result { - Ok(self.0.serialize_write_size()? - + self.1.serialize_write_size()? - + self.2.serialize_write_size()? - + self.3.serialize_write_size()? - + self.4.serialize_write_size()? - + self.5.serialize_write_size()? - + self.6.serialize_write_size()? - + self.7.serialize_write_size()? - + self.8.serialize_write_size()?) - } -} - -impl RmcSerialize for Box { +impl<'this, 'a, T: RmcSerialize<'this, 'a>> RmcSerialize<'this, 'a> for Box { #[inline(always)] fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { self.as_ref().serialize(writer) } #[inline(always)] - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { + fn deserialize( + reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { T::deserialize(reader).map(Box::new) } #[inline(always)] diff --git a/rnex-rmc/src/response.rs b/rnex-rmc/src/response.rs index 59ebf3e..ef72628 100644 --- a/rnex-rmc/src/response.rs +++ b/rnex-rmc/src/response.rs @@ -4,20 +4,22 @@ use crate::qresult::ERROR_MASK; use crate::serialization::Error; +use crate::{BorrowRead, RnexOwnedAnnotationRead}; use bytemuck::bytes_of; use rnex_util::SendingBufferConnection; -use std::io; +use std::borrow::Cow; +use std::io::{self, ErrorKind}; use std::io::{Read, Seek, Write}; use tracing::{error, warn}; use v_byte_helpers::EnumTryInto; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; #[derive(Debug, Clone)] -pub enum RMCResponseResult { +pub enum RMCResponseResult<'a> { Success { call_id: u32, method_id: u32, - data: Vec, + data: Cow<'a, [u8]>, }, Error { error_code: ErrorCode, @@ -26,13 +28,13 @@ pub enum RMCResponseResult { } #[derive(Debug, Clone)] -pub struct RMCResponse { +pub struct RMCResponse<'a> { pub protocol_id: u8, - pub response_result: RMCResponseResult, + pub response_result: RMCResponseResult<'a>, } -impl RMCResponse { - pub fn new(stream: &mut (impl Seek + Read)) -> io::Result { +impl<'a> RMCResponse<'a> { + pub fn new(stream: &mut (impl Seek + BorrowRead<'a>)) -> io::Result { // ignore the size for now this will only be used for checking let size: u32 = stream.read_struct(IS_BIG_ENDIAN)?; @@ -52,14 +54,13 @@ impl RMCResponse { let method_id: u32 = stream.read_struct(IS_BIG_ENDIAN)?; let method_id = method_id & (!0x8000); - let mut data: Vec = vec![0u8; (size - 2 - 4 - 4) as _]; - - stream.read(&mut data)?; + let data = stream.take_buffer(size.saturating_sub(10) as u64) + .ok_or(io::Error::new(ErrorKind::UnexpectedEof, "unable to get slice into return data due to specified size being longer than the data which was sent"))?; RMCResponseResult::Success { call_id, method_id, - data, + data: Cow::Borrowed(data), } } else { let error_code: u32 = stream.read_struct(IS_BIG_ENDIAN)?; @@ -142,6 +143,7 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re Ok(data_out) } +// todo: get rid of this inbetween allocation here somehow if possible pub async fn send_result( connection: &SendingBufferConnection, @@ -154,7 +156,7 @@ pub async fn send_result( Ok(v) => RMCResponseResult::Success { call_id, method_id, - data: v, + data: Cow::Owned(v), }, Err(e) => { warn!("error occurred during call: {:?}", e); @@ -173,7 +175,7 @@ pub async fn send_result( send_response(connection, response).await } -pub async fn send_response(connection: &SendingBufferConnection, rmcresponse: RMCResponse) { +pub async fn send_response<'a>(connection: &SendingBufferConnection, rmcresponse: RMCResponse<'a>) { connection.send(rmcresponse.to_data()).await; } diff --git a/rnex-rmc/src/serialization.rs b/rnex-rmc/src/serialization.rs index a15be3a..6fabd0e 100644 --- a/rnex-rmc/src/serialization.rs +++ b/rnex-rmc/src/serialization.rs @@ -1,10 +1,12 @@ use std::{ fmt::{self, Debug}, io::{self, Read, Write}, + str::Utf8Error, string::FromUtf8Error, + sync::RwLock, }; -use crate::helpers::DummyWriter; +use crate::{RnexOwnedAnnotationRead, helpers::DummyWriter}; use thiserror::Error; #[derive(Error, Debug)] @@ -12,7 +14,9 @@ pub enum Error { #[error("Io Error: {0}")] Io(#[from] io::Error), #[error("UTF8 conversion Error: {0}")] - Utf8(#[from] FromUtf8Error), + FromUtf8(#[from] FromUtf8Error), + #[error("UTF8 conversion Error: {0}")] + Utf8(#[from] Utf8Error), #[error("unexpected value: {0}")] UnexpectedValue(u64), #[cfg(feature = "rmc_struct_header")] @@ -32,7 +36,10 @@ pub enum Error { pub type Result = std::result::Result; -pub trait RmcSerialize { +pub trait RmcSerialize<'this, 'a>: 'this +where + 'this: 'a, +{ fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()>; fn serialize_write_size(&self) -> Result { let mut dummy = DummyWriter::new(); @@ -41,9 +48,9 @@ pub trait RmcSerialize { Ok(dummy.get_total_len()) } - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result + fn deserialize(reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized)) -> Result where - Self: Sized; + Self: Sized + 'this; fn to_data(&self) -> Result> { let expected_size = self.serialize_write_size()?; @@ -60,11 +67,13 @@ pub trait RmcSerialize { } } -impl RmcSerialize for () { +impl<'this, 'a> RmcSerialize<'this, 'a> for () { fn serialize(&self, _writer: &mut (impl Write + ?Sized)) -> Result<()> { Ok(()) } - fn deserialize(_reader: &mut (impl Read + ?Sized)) -> Result { + fn deserialize( + _reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { Ok(()) } fn serialize_write_size(&self) -> Result { @@ -72,6 +81,16 @@ impl RmcSerialize for () { } } +impl RmcStruct for () { + fn get_struct_info() -> &'static RmcStructInfo { + static INFO: RmcStructInfo = RmcStructInfo { + inheritors: RwLock::new(Vec::new()), + name: "Unit", + }; + &INFO + } +} + pub struct RmcStructInfo { // this may never be locked after initialization pub inheritors: std::sync::RwLock>, @@ -94,6 +113,6 @@ impl RmcStructInfo { } } -pub trait RmcStruct: RmcSerialize { +pub trait RmcStruct: for<'a, 'b> RmcSerialize<'a, 'b> { fn get_struct_info() -> &'static RmcStructInfo; } diff --git a/rnex-rmc/src/station_url.rs b/rnex-rmc/src/station_url.rs index 0aa187a..b48afc7 100644 --- a/rnex-rmc/src/station_url.rs +++ b/rnex-rmc/src/station_url.rs @@ -4,14 +4,19 @@ use std::str::FromStr; use rnex_util::station_url::StationUrl; +use crate::RnexOwnedAnnotationRead; use crate::{ helpers::DummyFormatWriter, serialization::{Error::StationUrlInvalid, Result, RmcSerialize}, }; -impl RmcSerialize for StationUrl { - fn deserialize(reader: &mut (impl Read + ?Sized)) -> Result { - let str = String::deserialize(reader)?; +impl<'this, 'a> RmcSerialize<'this, 'a> for StationUrl { + fn deserialize( + reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { + let mut rd = reader.subannotate("StationUrl"); + + let str = String::deserialize(&mut rd)?; Self::from_str(str.as_str()).map_err(|_| StationUrlInvalid) } diff --git a/rnex-rmc/src/string.rs b/rnex-rmc/src/string.rs index 011cd66..bef2658 100644 --- a/rnex-rmc/src/string.rs +++ b/rnex-rmc/src/string.rs @@ -3,11 +3,20 @@ use std::io::{Read, Write}; use tracing::error; use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions}; -use crate::serialization::{Result, RmcSerialize}; +use crate::{ + BorrowRead, RnexOwnedAnnotationRead, RnexReadObjectDisplay, + serialization::{Error, Result, RmcSerialize}, +}; -impl RmcSerialize for String { - fn deserialize(mut reader: &mut (impl Read + ?Sized)) -> Result { - let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?; +impl<'this, 'a> RmcSerialize<'this, 'a> for String { + fn deserialize( + mut reader: &mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { + let len: u16 = reader.owned_read("length", |r| { + Ok(u16::from_le_bytes( + *r.take_buffer_exact().ok_or(Error::OOB)?, + )) + })?; if len == 0 { return Ok("".to_string()); } @@ -28,9 +37,30 @@ impl RmcSerialize for String { } } -impl RmcSerialize for &str { - fn deserialize(_reader: &mut (impl Read + ?Sized)) -> Result { - panic!("cannot serialize to &str") +impl<'this, 'a> RmcSerialize<'this, 'a> for &'this str +where + 'this: 'a, +{ + fn deserialize( + reader: &'a mut (impl RnexOwnedAnnotationRead<'this, 'a> + ?Sized), + ) -> Result { + let mut rd = reader.subannotate("String"); + let len: u16 = rd.owned_read("length", |r| { + Ok(u16::from_le_bytes( + *r.take_buffer_exact().ok_or(Error::OOB)?, + )) + })?; + if len == 0 { + return Ok(""); + } + let text = rd.owned_read("text", |r| { + let raw = r.take_buffer(len as _).ok_or(Error::OOB)?; + if *raw.last().unwrap() != 0 { + error!("unable to find null terminator... continuing anyways"); + } + Ok(str::from_utf8(&raw[..raw.len() - 1])?) + })?; + Ok(text) } fn serialize(&self, writer: &mut (impl Write + ?Sized)) -> Result<()> { let u16_len: u16 = (self.len() + 1) as u16; diff --git a/rnex-server/src/lib.rs b/rnex-server/src/lib.rs index 4452179..43019b8 100644 --- a/rnex-server/src/lib.rs +++ b/rnex-server/src/lib.rs @@ -242,7 +242,7 @@ macro_rules! launch_rnex_module_server { .await?; let socket = $crate::tokio::net::TcpListener::bind(::std::net::SocketAddrV4::new(*$crate::OWN_IP_PRIVATE, *$crate::SERVER_PORT)) .instrument($crate::tracing::info_span!("binding to tcp socket")) - .await?; + .await.map_err(anyhow::Error::m)?; async move { while let Ok((mut stream, _addr)) = socket.accept().await { $crate::tracing::info!("new incoming connection"); diff --git a/rnex-util/src/lib.rs b/rnex-util/src/lib.rs index 2716646..6454fa2 100644 --- a/rnex-util/src/lib.rs +++ b/rnex-util/src/lib.rs @@ -5,6 +5,9 @@ pub mod date_time; pub mod result; pub mod station_url; +use std::fmt::Display; +use std::io::{Cursor, Read}; +use std::marker::PhantomData; use std::ops::Deref; use std::sync::{Arc, Weak}; use std::vec;