use std::collections::HashMap;
use serde_json::Value;
use crate::communication::parser_error::ParserError;
use crate::method::method_structure::{MethodArgument, MethodArguments};
pub struct ClientArgumentParserImpl {}
pub trait ClientArgumentParser {
fn parse(&self, method_arguments: Vec<MethodArgument>, arguments: &Value) -> Result<MethodArguments, ParserError>;
}
impl ClientArgumentParser for ClientArgumentParserImpl {
fn parse(&self, method_arguments: Vec<MethodArgument>, arguments: &Value) -> Result<MethodArguments, ParserError> {
if method_arguments.len() == 0 {
return Ok(MethodArguments::empty());
}
if !arguments.is_object() {
return Err(ParserError::new(None, String::from("Arguments has to be an object")));
}
self.parse_arguments_to_list(&method_arguments, &arguments)
}
}
impl ClientArgumentParserImpl {
fn parse_arguments_to_list(&self, method_arguments: &Vec<MethodArgument>, arguments: &Value) -> Result<MethodArguments, ParserError> {
let mut argument_map: HashMap<String, Value> = HashMap::new();
let arguments_object = arguments.as_object().unwrap();
for argument in method_arguments {
let argument_value = arguments_object.get(&argument.name);
if argument_value.is_none() && !argument.required {
continue;
}
if argument_value.is_none() {
return Err(ParserError::new(None, String::from(format!("Argument {} is required", argument.name))));
}
argument_map.insert(argument.name.clone(), argument_value.unwrap().clone().take());
}
Ok(MethodArguments::new(argument_map))
}
}