Ensure fields are not escaped when inserted as object keys

This commit is contained in:
Tobie Morgan Hitchcock 2022-05-31 20:44:27 +01:00
parent 3f568f3990
commit 4d9b3fd403
5 changed files with 49 additions and 9 deletions

View file

@ -43,6 +43,12 @@ impl Deref for Ident {
}
}
impl Ident {
pub fn to_raw(&self) -> String {
self.0.to_string()
}
}
impl fmt::Display for Ident {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", escape_ident(&self.0))

View file

@ -45,6 +45,12 @@ impl Deref for Idiom {
}
}
impl From<String> for Idiom {
fn from(v: String) -> Self {
Idiom(vec![Part::from(v)])
}
}
impl From<Vec<Part>> for Idiom {
fn from(v: Vec<Part>) -> Self {
Idiom(v)
@ -61,6 +67,15 @@ impl Idiom {
pub fn to_path(&self) -> String {
format!("/{}", self).replace(']', "").replace(&['.', '['][..], "/")
}
///
pub fn simplify(&self) -> Idiom {
self.0
.iter()
.cloned()
.filter(|p| matches!(p, Part::Field(_) | Part::Graph(_)))
.collect::<Vec<_>>()
.into()
}
}
impl Idiom {

View file

@ -91,7 +91,7 @@ impl Object {
Some(o) => match self.get("path") {
Some(p) => Ok(Operation {
op: o.into(),
path: p.to_idiom(),
path: p.jsonpath(),
value: match self.get("value") {
Some(v) => v.clone(),
None => Value::Null,

View file

@ -29,7 +29,7 @@ impl Value {
_ => {
let mut obj = Value::base();
obj.set(ctx, opt, txn, path.next(), val).await?;
v.insert(f.to_string(), obj);
v.insert(f.to_raw(), obj);
Ok(())
}
},

View file

@ -639,13 +639,18 @@ impl Value {
}
pub fn to_idiom(&self) -> Idiom {
self.to_strand()
.as_str()
.trim_start_matches('/')
.split(&['.', '/'][..])
.map(Part::from)
.collect::<Vec<Part>>()
.into()
match self {
Value::Idiom(v) => v.simplify(),
Value::Strand(v) => v.0.to_string().into(),
Value::Datetime(v) => v.0.to_string().into(),
Value::Function(v) => match v.as_ref() {
Function::Future(_) => "fn::future".to_string().into(),
Function::Script(_) => "fn::script".to_string().into(),
Function::Normal(f, _) => f.to_string().into(),
_ => v.to_string().into(),
},
_ => self.to_string().into(),
}
}
// -----------------------------------
@ -738,6 +743,20 @@ impl Value {
}
}
// -----------------------------------
// JSON Path conversion
// -----------------------------------
pub fn jsonpath(&self) -> Idiom {
self.to_strand()
.as_str()
.trim_start_matches('/')
.split(&['.', '/'][..])
.map(Part::from)
.collect::<Vec<Part>>()
.into()
}
// -----------------------------------
// Value operations
// -----------------------------------