Skip to content

Commit

Permalink
return an on type clashes
Browse files Browse the repository at this point in the history
  • Loading branch information
ducaale committed Feb 5, 2022
1 parent d6a837f commit faf2162
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 20 deletions.
78 changes: 70 additions & 8 deletions src/nested_json.rs
Original file line number Diff line number Diff line change
@@ -1,12 1,12 @@
use std::mem;
use std::{fmt, mem};

use anyhow::{anyhow, Result};
use serde_json::map::Map;
use serde_json::Value;

use crate::utils::unescape;

#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PathComponent {
Key(String, Option<(usize, usize)>),
Index(Option<usize>, (usize, usize)),
Expand Down Expand Up @@ -112,15 112,77 @@ pub fn parse_path(raw_json_path: &str) -> Result<Vec<PathComponent>> {
Ok(json_path)
}

#[derive(Debug)]
pub struct TypeError {
root: Value,
path_component: PathComponent,
json_path: Option<String>,
}

impl TypeError {
fn new(root: Value, path_component: PathComponent) -> Self {
TypeError {
root,
path_component,
json_path: None,
}
}

pub fn with_json_path(mut self, json_path: String) -> TypeError {
self.json_path = Some(json_path);
self
}
}

impl fmt::Display for TypeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let root_type = match self.root {
Value::Null => "null",
Value::Bool(_) => "bool",
Value::Number(_) => "number",
Value::String(_) => "string",
Value::Array(_) => "array",
Value::Object(_) => "object",
};
let (access_type, i) = match self.path_component {
PathComponent::Index(_, (i, _)) => ("index", i),
PathComponent::Key(_, Some((i, _))) => ("key", i),
PathComponent::Key(_, None) => unreachable!(),
};

if let Some(json_path) = &self.json_path {
write!(
f,
"Can't perform '{}' based access on '{}' which has type of '{}'",
access_type,
&json_path[..i],
root_type
)
} else {
write!(
f,
"Can't perform '{}' based access on '{}'",
access_type, root_type
)
}
}
}

impl std::error::Error for TypeError {}

// TODO: add comment here
pub fn set_value(root: Option<Value>, path: &[PathComponent], value: Value) -> Result<Value> {
pub fn set_value(
root: Option<Value>,
path: &[PathComponent],
value: Value,
) -> std::result::Result<Value, TypeError> {
debug_assert!(!path.is_empty(), "path should not be empty");
Ok(match root {
Some(Value::Object(mut obj)) => {
let key = match &path[0] {
PathComponent::Key(v, ..) => v.to_string(),
key @ PathComponent::Index(..) => {
todo!("current key: {:?}, root: {:?}", key, Value::Object(obj))
path_component @ PathComponent::Index(..) => {
return Err(TypeError::new(Value::Object(obj), path_component.clone()))
}
};
if path.len() == 1 {
Expand All @@ -134,8 196,8 @@ pub fn set_value(root: Option<Value>, path: &[PathComponent], value: Value) -> R
}
Some(Value::Array(mut arr)) => {
let index = match &path[0] {
index @ PathComponent::Key(..) => {
todo!("current index: {:?}, root: {:?}", index, Value::Array(arr))
path_component @ PathComponent::Key(..) => {
return Err(TypeError::new(Value::Array(arr), path_component.clone()))
}
PathComponent::Index(Some(v), ..) => *v,
PathComponent::Index(None, ..) => arr.len(),
Expand All @@ -153,7 215,7 @@ pub fn set_value(root: Option<Value>, path: &[PathComponent], value: Value) -> R
if path.len() == 1 {
value
} else {
todo!("current ???: {:?}, root: {:?}", path[0], root);
return Err(TypeError::new(root, path[0].clone()));
}
}
None => match path[0] {
Expand Down
24 changes: 12 additions & 12 deletions src/request_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,29 297,29 @@ impl RequestItems {
match item {
RequestItem::JsonField(raw_key, value) => {
let json_path = nested_json::parse_path(&raw_key)?;
body = Some(nested_json::set_value(body, &json_path, value)?);
body = nested_json::set_value(body, &json_path, value)
.map_err(|e| e.with_json_path(raw_key))?
.into();
}
RequestItem::JsonFieldFromFile(raw_key, value) => {
let value = serde_json::from_str(&fs::read_to_string(expand_tilde(value))?)?;
let json_path = nested_json::parse_path(&raw_key)?;
body = Some(nested_json::set_value(body, &json_path, value)?);
body = nested_json::set_value(body, &json_path, value)
.map_err(|e| e.with_json_path(raw_key))?
.into()
}
RequestItem::DataField { raw_key, value, .. } => {
let json_path = nested_json::parse_path(&raw_key)?;
body = Some(nested_json::set_value(
body,
&json_path,
Value::String(value),
)?);
body = nested_json::set_value(body, &json_path, Value::String(value))
.map_err(|e| e.with_json_path(raw_key))?
.into();
}
RequestItem::DataFieldFromFile { raw_key, value, .. } => {
let value = fs::read_to_string(expand_tilde(value))?;
let json_path = nested_json::parse_path(&raw_key)?;
body = Some(nested_json::set_value(
body,
&json_path,
Value::String(value),
)?);
body = nested_json::set_value(body, &json_path, Value::String(value))
.map_err(|e| e.with_json_path(raw_key))?
.into();
}
RequestItem::FormFile { .. } => unreachable!(),
RequestItem::HttpHeader(..) => {}
Expand Down

0 comments on commit faf2162

Please sign in to comment.