Skip to main content

wpl/eval/builtins/
hex.rs

1use bytes::Bytes;
2use orion_error::{ErrorOwe, ErrorWith};
3use std::sync::Arc;
4
5use wp_model_core::raw::RawData;
6use wp_parse_api::{PipeProcessor, WparseResult};
7
8#[derive(Debug)]
9pub struct HexProc;
10
11impl PipeProcessor for HexProc {
12    /// Decodes hex-encoded data while preserving the input container type.
13    /// For string inputs, attempts UTF-8 conversion but falls back to bytes on invalid UTF-8.
14    fn process(&self, data: RawData) -> WparseResult<RawData> {
15        match data {
16            RawData::String(s) => {
17                let decoded = hex::decode(s.as_bytes()).owe_data().want("hex decode")?;
18                let vstring = String::from_utf8(decoded).owe_data().want("to-json")?;
19                Ok(RawData::from_string(vstring))
20            }
21            RawData::Bytes(b) => {
22                let decoded = hex::decode(b.as_ref()).owe_data().want("hex decode")?;
23                Ok(RawData::Bytes(Bytes::from(decoded)))
24            }
25            RawData::ArcBytes(b) => {
26                let decoded = hex::decode(b.as_ref()).owe_data().want("hex decode")?;
27                // 注意:RawData::ArcBytes 现在使用 Arc<Vec<u8>>
28                Ok(RawData::ArcBytes(Arc::new(decoded)))
29            }
30        }
31    }
32
33    fn name(&self) -> &'static str {
34        "decode/hex"
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use crate::types::AnyResult;
41    use bytes::Bytes;
42    use std::sync::Arc;
43
44    use super::*;
45
46    #[test]
47    fn test_hex() -> AnyResult<()> {
48        let data = RawData::from_string("48656c6c6f20776f726c6421".to_string());
49        let y = HexProc.process(data)?;
50        assert_eq!(
51            crate::eval::builtins::raw_to_utf8_string(&y),
52            "Hello world!"
53        );
54
55        // Test with a longer complex hex string
56        let data = RawData::from_string("5468697320697320612074657374206f6620612068657820656e636f64656420737472696e672120405f5f252026262a2b2b".to_string());
57        let what = HexProc.process(data)?;
58        let decoded = crate::eval::builtins::raw_to_utf8_string(&what);
59        assert!(decoded.starts_with("This is a test of a hex encoded string! @__% &&*++"));
60
61        let bytes_data = RawData::Bytes(Bytes::from_static(b"48656c6c6f"));
62        let result = HexProc.process(bytes_data)?;
63        assert!(matches!(result, RawData::Bytes(_)));
64        assert_eq!(crate::eval::builtins::raw_to_utf8_string(&result), "Hello");
65
66        let arc_data = RawData::ArcBytes(Arc::new(b"48656c6c6f20776f726c64".to_vec()));
67        let result = HexProc.process(arc_data)?;
68        assert!(matches!(result, RawData::ArcBytes(_)));
69        assert_eq!(
70            crate::eval::builtins::raw_to_utf8_string(&result),
71            "Hello world"
72        );
73        Ok(())
74    }
75}