#[doc(hidden)]
#[cfg(feature = "std")]
extern crate std;
use crate::{BehaviorState, ConstString, behavior::MockBehaviorConfig, factory::registry::SubstitutionRule};
use alloc::{collections::btree_map::BTreeMap, string::String};
use core::{str::FromStr, time::Duration};
use nanoserde::{DeJson, DeJsonTok};
#[derive(Debug, Default)]
pub struct JsonConfig {
pub substitution_rules: BTreeMap<ConstString, SubstitutionRule>,
}
#[allow(clippy::too_many_lines)]
#[allow(clippy::single_match_else)]
impl DeJson for JsonConfig {
fn de_json(state: &mut nanoserde::DeJsonState, input: &mut core::str::Chars) -> Result<Self, nanoserde::DeJsonErr> {
let mut result = Self::default();
let mut mock_behavior_configs: BTreeMap<String, MockBehaviorConfig> = BTreeMap::new();
match state.tok {
DeJsonTok::CurlyOpen => {
while state.tok != DeJsonTok::CurlyClose {
state.next_tok(input)?;
match state.tok {
DeJsonTok::Str => match state.strbuf.as_ref() {
"MockBehaviorConfigs" => {
while state.tok != DeJsonTok::CurlyOpen && state.tok != DeJsonTok::Eof {
state.next_tok(input)?;
}
state.next_tok(input)?;
while state.tok != DeJsonTok::CurlyClose && state.tok != DeJsonTok::Eof {
let config_name = state.strbuf.clone();
let mut config = MockBehaviorConfig::default();
while state.tok != DeJsonTok::CurlyOpen {
state.next_tok(input)?;
}
state.next_tok(input)?;
while state.tok != DeJsonTok::CurlyClose && state.tok != DeJsonTok::Eof {
let field = state.strbuf.clone();
state.next_tok(input)?;
state.next_tok(input)?;
match field.as_ref() {
"return_status" => {
let behavior_state =
BehaviorState::from_str(&state.strbuf).map_err(|_x| {
nanoserde::DeJsonErr {
line: state.line,
col: state.col,
msg: nanoserde::DeJsonErrReason::CannotParse(
state.strbuf.clone(),
),
}
})?;
config.return_state = behavior_state;
state.next_tok(input)?;
}
"async_delay" => {
let value: u64 =
u64::from_str(&state.numbuf).map_err(|_x| nanoserde::DeJsonErr {
line: state.line,
col: state.col,
msg: nanoserde::DeJsonErrReason::CannotParse(state.strbuf.clone()),
})?;
config.async_delay = Some(Duration::from_millis(value));
}
"failure_script" => {
config.failure_script = Some((*state.strbuf).into());
state.next_tok(input)?;
}
"success_script" => {
config.success_script = Some((*state.strbuf).into());
state.next_tok(input)?;
}
"post_script" => {
config.post_script = Some((*state.strbuf).into());
state.next_tok(input)?;
}
_ => {
return Err(nanoserde::DeJsonErr {
line: state.line,
col: state.col,
msg: nanoserde::DeJsonErrReason::UnexpectedToken(
state.tok.clone(),
state.strbuf.clone(),
),
});
}
}
while state.tok != DeJsonTok::Str
&& state.tok != DeJsonTok::CurlyClose
&& state.tok != DeJsonTok::Eof
{
state.next_tok(input)?;
}
if state.tok == DeJsonTok::CurlyClose {
mock_behavior_configs.insert(config_name, config);
state.next_tok(input)?;
break;
}
}
while state.tok != DeJsonTok::Str
&& state.tok != DeJsonTok::CurlyClose
&& state.tok != DeJsonTok::Eof
{
state.next_tok(input)?;
}
if state.tok == DeJsonTok::CurlyClose {
state.next_tok(input)?;
break;
}
}
}
"SubstitutionRules" => {
while state.tok != DeJsonTok::CurlyOpen && state.tok != DeJsonTok::Eof {
state.next_tok(input)?;
}
state.next_tok(input)?;
while state.tok != DeJsonTok::CurlyClose && state.tok != DeJsonTok::Eof {
let key = state.strbuf.clone();
state.next_tok(input)?;
while state.tok != DeJsonTok::Str
&& state.tok != DeJsonTok::CurlyClose
&& state.tok != DeJsonTok::Eof
{
state.next_tok(input)?;
}
let value = state.strbuf.clone();
let rule = mock_behavior_configs.get(&value).map_or_else(
|| SubstitutionRule::StringRule(value.into()),
|config| SubstitutionRule::ConfigRule(config.clone()),
);
result.substitution_rules.insert(key.into(), rule);
state.next_tok(input)?;
while state.tok != DeJsonTok::Str
&& state.tok != DeJsonTok::CurlyClose
&& state.tok != DeJsonTok::Eof
{
state.next_tok(input)?;
}
if state.tok == DeJsonTok::CurlyClose {
state.next_tok(input)?;
break;
}
}
}
_ => {
return Err(nanoserde::DeJsonErr {
line: state.line,
col: state.col,
msg: nanoserde::DeJsonErrReason::UnexpectedToken(
state.tok.clone(),
state.strbuf.clone(),
),
});
}
},
_ => {
return Err(nanoserde::DeJsonErr {
line: state.line,
col: state.col,
msg: nanoserde::DeJsonErrReason::UnexpectedToken(state.tok.clone(), state.strbuf.clone()),
});
}
}
}
}
_ => {
return Err(nanoserde::DeJsonErr {
line: state.line,
col: state.col,
msg: nanoserde::DeJsonErrReason::UnexpectedToken(state.tok.clone(), state.strbuf.clone()),
});
}
}
Ok(result)
}
}