1use bincode::de::{BorrowDecoder, Decoder};
2use bincode::enc::Encoder;
3use bincode::error::{DecodeError, EncodeError};
4use bincode::{BorrowDecode, Decode as dDecode, Decode, Encode, Encode as dEncode};
5use compact_str::CompactString;
6use cu29_clock::{PartialCuTimeRange, Tov};
7use serde::{Deserialize, Serialize};
8use std::error::Error;
9use std::fmt::{Debug, Display, Formatter};
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct CuError {
14 message: String,
15 cause: Option<String>,
16}
17
18impl Display for CuError {
19 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
20 let context_str = match &self.cause {
21 Some(c) => c.to_string(),
22 None => "None".to_string(),
23 };
24 write!(f, "{}\n context:{}", self.message, context_str)?;
25 Ok(())
26 }
27}
28
29impl Error for CuError {}
30
31impl From<&str> for CuError {
32 fn from(s: &str) -> CuError {
33 CuError {
34 message: s.to_string(),
35 cause: None,
36 }
37 }
38}
39
40impl From<String> for CuError {
41 fn from(s: String) -> CuError {
42 CuError {
43 message: s,
44 cause: None,
45 }
46 }
47}
48
49impl CuError {
50 pub fn new_with_cause(message: &str, cause: impl Error) -> CuError {
51 CuError {
52 message: message.to_string(),
53 cause: Some(cause.to_string()),
54 }
55 }
56
57 pub fn add_cause(mut self, context: &str) -> CuError {
58 self.cause = Some(context.into());
59 self
60 }
61}
62
63pub type CuResult<T> = Result<T, CuError>;
65
66pub trait WriteStream<E: Encode>: Sync + Send + Debug {
68 fn log(&mut self, obj: &E) -> CuResult<()>;
69 fn flush(&mut self) -> CuResult<()> {
70 Ok(())
71 }
72}
73
74#[derive(dEncode, dDecode, Copy, Clone, Debug, PartialEq)]
76pub enum UnifiedLogType {
77 Empty, StructuredLogLine, CopperList, FrozenTasks, LastEntry, }
83pub trait Metadata: Default + Debug + Clone + Encode + Decode<()> + Serialize {}
85
86impl Metadata for () {}
87
88pub trait CuMsgMetadataTrait {
90 fn process_time(&self) -> PartialCuTimeRange;
92
93 fn status_txt(&self) -> &CuCompactString;
95}
96
97pub trait ErasedCuStampedData {
99 fn payload(&self) -> Option<&dyn erased_serde::Serialize>;
100 fn tov(&self) -> Tov;
101 fn metadata(&self) -> &dyn CuMsgMetadataTrait;
102}
103
104pub trait ErasedCuStampedDataSet {
107 fn cumsgs(&self) -> Vec<&dyn ErasedCuStampedData>;
108}
109
110pub trait MatchingTasks {
112 fn get_all_task_ids() -> &'static [&'static str];
113}
114
115pub trait CopperListTuple:
117 bincode::Encode + bincode::Decode<()> + Debug + Serialize + ErasedCuStampedDataSet + MatchingTasks
118{
119} impl<T> CopperListTuple for T where
123 T: bincode::Encode
124 + bincode::Decode<()>
125 + Debug
126 + Serialize
127 + ErasedCuStampedDataSet
128 + MatchingTasks
129{
130}
131
132pub const COMPACT_STRING_CAPACITY: usize = size_of::<String>();
136
137#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
138pub struct CuCompactString(pub CompactString);
139
140impl Encode for CuCompactString {
141 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
142 let CuCompactString(ref compact_string) = self;
143 let bytes = compact_string.as_bytes();
144 bytes.encode(encoder)
145 }
146}
147
148impl<Context> Decode<Context> for CuCompactString {
149 fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
150 let bytes = <Vec<u8> as Decode<D::Context>>::decode(decoder)?; let compact_string =
152 CompactString::from_utf8(bytes).map_err(|e| DecodeError::Utf8 { inner: e })?;
153 Ok(CuCompactString(compact_string))
154 }
155}
156
157impl<'de, Context> BorrowDecode<'de, Context> for CuCompactString {
158 fn borrow_decode<D: BorrowDecoder<'de>>(decoder: &mut D) -> Result<Self, DecodeError> {
159 CuCompactString::decode(decoder)
160 }
161}