libbarto/message/shared/
failed.rs

1// Copyright (c) 2025 barto developers
2//
3// Licensed under the Apache License, Version 2.0
4// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. All files in the project carrying such notice may not be copied,
7// modified, or distributed except according to those terms.
8
9use bincode::{
10    BorrowDecode, Decode, Encode,
11    de::{BorrowDecoder, Decoder},
12    enc::Encoder,
13    error::{DecodeError, EncodeError},
14};
15use bon::Builder;
16use getset::{CopyGetters, Getters};
17
18use crate::OffsetDataTimeWrapper;
19#[cfg(test)]
20use crate::utils::Mock;
21
22/// The output of a `Failed` request
23#[derive(Builder, Clone, CopyGetters, Debug, Getters, PartialEq)]
24pub struct FailedOutput {
25    /// The timestamp of when the output was generated
26    #[getset(get = "pub")]
27    timestamp: Option<OffsetDataTimeWrapper>,
28    /// The name of the bartoc client
29    #[getset(get = "pub")]
30    bartoc_name: Option<String>,
31    /// The name of the command that failed
32    #[getset(get = "pub")]
33    cmd_name: Option<String>,
34    /// The data returned from the command
35    #[getset(get = "pub")]
36    data: Option<String>,
37    /// The exit code of the command
38    #[getset(get_copy = "pub")]
39    exit_code: u8,
40    /// Whether the command was successful
41    #[getset(get_copy = "pub")]
42    success: i8,
43}
44
45#[cfg(test)]
46impl Mock for FailedOutput {
47    fn mock() -> Self {
48        Self {
49            timestamp: Some(OffsetDataTimeWrapper::mock()),
50            bartoc_name: Some("mock_bartoc".to_string()),
51            cmd_name: Some("mock_cmd".to_string()),
52            data: Some("mock_data".to_string()),
53            exit_code: 1,
54            success: 0,
55        }
56    }
57}
58
59impl<Context> Decode<Context> for FailedOutput {
60    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
61        Ok(Self {
62            timestamp: Decode::decode(decoder)?,
63            bartoc_name: Decode::decode(decoder)?,
64            cmd_name: Decode::decode(decoder)?,
65            data: Decode::decode(decoder)?,
66            exit_code: Decode::decode(decoder)?,
67            success: Decode::decode(decoder)?,
68        })
69    }
70}
71
72impl<'de, Context> BorrowDecode<'de, Context> for FailedOutput {
73    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
74        decoder: &mut D,
75    ) -> Result<Self, DecodeError> {
76        Ok(Self {
77            timestamp: BorrowDecode::borrow_decode(decoder)?,
78            bartoc_name: BorrowDecode::borrow_decode(decoder)?,
79            cmd_name: BorrowDecode::borrow_decode(decoder)?,
80            data: BorrowDecode::borrow_decode(decoder)?,
81            exit_code: BorrowDecode::borrow_decode(decoder)?,
82            success: BorrowDecode::borrow_decode(decoder)?,
83        })
84    }
85}
86
87impl Encode for FailedOutput {
88    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
89        Encode::encode(&self.timestamp, encoder)?;
90        Encode::encode(&self.bartoc_name, encoder)?;
91        Encode::encode(&self.cmd_name, encoder)?;
92        Encode::encode(&self.data, encoder)?;
93        Encode::encode(&self.exit_code, encoder)?;
94        Encode::encode(&self.success, encoder)?;
95        Ok(())
96    }
97}
98
99#[cfg(test)]
100mod test {
101    use super::FailedOutput;
102
103    use crate::utils::Mock;
104    use anyhow::Result;
105    use bincode::{config::standard, decode_from_slice, encode_to_vec};
106
107    #[test]
108    fn test_failed_output_encode_decode() -> Result<()> {
109        let original = FailedOutput::mock();
110
111        // Encode
112        let encoded = encode_to_vec(&original, standard())?;
113        let (decoded, _): (FailedOutput, usize) = decode_from_slice(&encoded, standard())?;
114        let (borrow_decoded, _): (FailedOutput, usize) =
115            bincode::borrow_decode_from_slice(&encoded, standard())?;
116
117        assert_eq!(original, decoded);
118        assert_eq!(original, borrow_decoded);
119        Ok(())
120    }
121}