wpl/eval/value/parser/
factory.rs1use orion_error::OperationContext;
2use orion_error::conversion::{ErrorWith, ToStructError};
3
4use crate::eval::value::parse_def::{Hold, ParserHold};
5use crate::eval::value::parser::base::digit::{DigitP, FloatP};
6use crate::eval::value::parser::base::hex::HexDigitP;
7use crate::eval::value::parser::base::*;
8use crate::eval::value::parser::compute::device::SnP;
9use crate::eval::value::parser::network::http;
10use crate::eval::value::parser::network::net::{IpNetP, IpPSR};
11use crate::eval::value::parser::physical::time::{
12 TimeCLF, TimeISOP, TimeP, TimeRFC2822, TimeRFC3339, TimeStampPSR,
13};
14use crate::eval::value::parser::protocol::array::ArrayP;
15use crate::eval::value::parser::protocol::base64::Base64P;
16use crate::eval::value::parser::protocol::json::JsonP;
17use crate::eval::value::parser::protocol::json_exact::ExactJsonP;
18use crate::eval::value::parser::protocol::keyval::KeyValP;
19use crate::eval::value::parser::protocol::kvarr::KvArrP;
20use crate::eval::value::parser::protocol::proto_text::ProtoTextP;
21use crate::parser::error::{WplCodeError, WplCodeReason, WplCodeResult};
22use wp_model_core::model::DataType;
23
24use super::auto::CombinedParser;
25#[derive(Default)]
26pub struct ParserFactory {}
27
28impl ParserFactory {
29 pub fn crate_auto() -> WplCodeResult<ParserHold> {
30 let mut parse = CombinedParser::new();
31 parse.ps.push(ParserFactory::create(&DataType::Json)?);
32 parse.ps.push(ParserFactory::create(&DataType::Time)?);
33 parse.ps.push(ParserFactory::create(&DataType::IP)?);
34 parse.ps.push(ParserFactory::create(&DataType::KV)?);
35 parse.ps.push(ParserFactory::create(&DataType::Float)?);
36 parse.ps.push(ParserFactory::create(&DataType::Digit)?);
37 parse.ps.push(ParserFactory::create(&DataType::Hex)?);
38 parse.ps.push(ParserFactory::create(&DataType::Chars)?);
39 Ok(Hold::new(parse))
40 }
41
42 pub fn create_simple(meta: &DataType) -> Option<ParserHold> {
43 match *meta {
44 DataType::Bool => Some(Hold::new(BoolP::default())),
45 DataType::Chars => Some(Hold::new(CharsP::default())),
46 DataType::Symbol => Some(Hold::new(SymbolP::default())),
47 DataType::PeekSymbol => Some(Hold::new(PeekSymbolP::default())),
48 DataType::Digit => Some(Hold::new(DigitP::default())),
49 DataType::Float => Some(Hold::new(FloatP::default())),
50 DataType::Ignore => Some(Hold::new(IgnoreP::default())),
51 DataType::Time => Some(Hold::new(TimeP::default())),
52 DataType::TimeCLF => Some(Hold::new(TimeCLF::default())),
53 DataType::TimeISO => Some(Hold::new(TimeISOP::default())),
54 DataType::TimeRFC3339 => Some(Hold::new(TimeRFC3339::default())),
55 DataType::TimeRFC2822 => Some(Hold::new(TimeRFC2822::default())),
56 DataType::TimeTIMESTAMP => Some(Hold::new(TimeStampPSR::default())),
57 DataType::IP => Some(Hold::new(IpPSR::default())),
58 DataType::IpNet => Some(Hold::new(IpNetP::default())),
59 DataType::Port => Some(Hold::new(DigitP::default())),
60 DataType::SN => Some(Hold::new(SnP::default())),
61 DataType::Hex => Some(Hold::new(HexDigitP::default())),
62 DataType::Base64 => Some(Hold::new(Base64P::default())),
63 DataType::KvArr => Some(Hold::new(KvArrP::default())),
64 DataType::KV => Some(Hold::new(KeyValP::default())),
65 DataType::Json => Some(Hold::new(JsonP::default())),
66 DataType::ExactJson => Some(Hold::new(ExactJsonP::default())),
67 DataType::HttpRequest => Some(Hold::new(http::RequestP::default())),
68 DataType::HttpStatus => Some(Hold::new(http::StatusP::default())),
69 DataType::HttpAgent => Some(Hold::new(http::AgentP::default())),
70 DataType::HttpMethod => Some(Hold::new(http::MethodP::default())),
71 DataType::ProtoText => Some(Hold::new(ProtoTextP::default())),
72 _ => None,
73 }
74 }
75
76 fn create_l1(meta: &DataType) -> WplCodeResult<ParserHold> {
77 let mut ctx = OperationContext::doing("create parser");
78 ctx.record("meta", meta.to_string());
79 if let Some(hold) = Self::create_simple(meta) {
80 return Ok(hold);
81 } else if DataType::Auto == *meta {
82 return Self::crate_auto();
83 }
84 Err(WplCodeError::builder(WplCodeReason::UnSupport)
85 .detail(meta.to_string())
86 .finish())
87 .with_context(&ctx)
88 }
89
90 pub fn create(meta: &DataType) -> WplCodeResult<ParserHold> {
91 let mut ctx = OperationContext::doing("create parser");
92 ctx.record("meta", meta.to_string());
93 if let DataType::Array(next_name) = meta {
94 let sub_meta = DataType::from(next_name.as_str())
95 .map_err(|e| {
96 WplCodeReason::UnSupport
97 .to_err()
98 .with_detail(format!("unsupported data type: {}: {}", next_name, e))
99 })
101 .with_context(&ctx)?;
102
103 match Self::create(&sub_meta) {
111 Ok(_) => Ok(Hold::new(ArrayP::new())),
112 Err(e) => Err(e),
113 }
114 } else {
115 Self::create_l1(meta)
116 }
117 }
118}