use base64::{Engine as _, engine::general_purpose};
use bytes::Bytes;
use orion_error::conversion::{ErrorWith, SourceRawErr};
use std::sync::Arc;
use wp_model_core::raw::RawData;
use wp_parse_api::{PipeProcessor, WparseReason, WparseResult};
#[derive(Debug)]
pub struct Base64Proc;
impl PipeProcessor for Base64Proc {
fn process(&self, data: RawData) -> WparseResult<RawData> {
match data {
RawData::String(s) => {
let decoded = general_purpose::STANDARD
.decode(s.as_bytes())
.source_raw_err(WparseReason::data_error(), "base64 decode")
.doing("base64 decode")?;
let vstring = String::from_utf8(decoded)
.source_raw_err(WparseReason::data_error(), "utf8 to json")
.doing("to-json")?;
Ok(RawData::from_string(vstring))
}
RawData::Bytes(b) => {
let decoded = general_purpose::STANDARD
.decode(b.as_ref())
.source_raw_err(WparseReason::data_error(), "base64 decode bytes")
.doing("base64 decode")?;
Ok(RawData::Bytes(Bytes::from(decoded)))
}
RawData::ArcBytes(b) => {
let decoded = general_purpose::STANDARD
.decode(b.as_ref())
.source_raw_err(WparseReason::data_error(), "base64 decode arc bytes")
.doing("base64 decode")?;
Ok(RawData::ArcBytes(Arc::new(decoded)))
}
}
}
fn name(&self) -> &'static str {
"decode/base64"
}
}
#[cfg(test)]
mod tests {
use crate::parser::error::IntoWplCodeError;
use crate::parser::error::WplCodeResult;
use super::*;
#[test]
fn test_base64() -> WplCodeResult<()> {
let data = RawData::from_string("aGVsbG8=".to_string());
let y = Base64Proc.process(data).map_err(|e| e.into_wpl_err())?;
assert_eq!(crate::eval::builtins::raw_to_utf8_string(&y), "hello");
let data = RawData::from_string("VGhpcyBpcyBhIHRlc3Qgb2YgYSBiYXNlNjQgZW5jb2RlZCBzdHJpbmcgd2l0aCBzcGVjaWFsIGNoYXJhY3RlcnMhIEBfXyUgJiYqKys=".to_string());
let what = Base64Proc.process(data).map_err(|e| e.into_wpl_err())?;
let decoded = crate::eval::builtins::raw_to_utf8_string(&what);
assert!(decoded.starts_with(
"This is a test of a base64 encoded string with special characters! @__% &&*++"
));
let bytes_data = RawData::Bytes(Bytes::from_static(b"aGVsbG8="));
let result = Base64Proc
.process(bytes_data)
.map_err(|e| e.into_wpl_err())?;
assert!(matches!(result, RawData::Bytes(_)));
assert_eq!(crate::eval::builtins::raw_to_utf8_string(&result), "hello");
let arc_data = RawData::ArcBytes(Arc::new(b"Zm9vYmFy".to_vec()));
let result = Base64Proc.process(arc_data).map_err(|e| e.into_wpl_err())?;
assert!(matches!(result, RawData::ArcBytes(_)));
assert_eq!(crate::eval::builtins::raw_to_utf8_string(&result), "foobar");
Ok(())
}
}