Implement SQL Idiom as a newtype tuple struct

This commit is contained in:
Tobie Morgan Hitchcock 2022-05-05 12:26:46 +01:00
parent 041f220727
commit 89f731c903
2 changed files with 29 additions and 75 deletions

View file

@ -36,39 +36,34 @@ pub fn locals(i: &str) -> IResult<&str, Idioms> {
} }
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)] #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Idiom { pub struct Idiom(pub Vec<Part>);
pub parts: Vec<Part>,
}
impl Deref for Idiom { impl Deref for Idiom {
type Target = [Part]; type Target = [Part];
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
self.parts.as_slice() self.0.as_slice()
} }
} }
impl From<String> for Idiom { impl From<String> for Idiom {
fn from(v: String) -> Self { fn from(v: String) -> Self {
Idiom { Idiom(vec![Part::from(v)])
parts: vec![Part::from(v)],
}
} }
} }
impl From<Vec<Part>> for Idiom { impl From<Vec<Part>> for Idiom {
fn from(v: Vec<Part>) -> Self { fn from(v: Vec<Part>) -> Self {
Idiom { Idiom(v)
parts: v,
}
} }
} }
impl Idiom { impl Idiom {
///
pub fn push(mut self, n: Part) -> Idiom { pub fn push(mut self, n: Part) -> Idiom {
self.parts.push(n); self.0.push(n);
self self
} }
///
pub fn to_path(&self) -> String { pub fn to_path(&self) -> String {
format!("/{}", self).replace(']', "").replace(&['.', '['][..], "/") format!("/{}", self).replace(']', "").replace(&['.', '['][..], "/")
} }
@ -96,7 +91,7 @@ impl fmt::Display for Idiom {
write!( write!(
f, f,
"{}", "{}",
self.parts self.0
.iter() .iter()
.enumerate() .enumerate()
.map(|(i, p)| match (i, p) { .map(|(i, p)| match (i, p) {
@ -154,12 +149,7 @@ mod tests {
assert!(res.is_ok()); assert!(res.is_ok());
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("test", format!("{}", out)); assert_eq!("test", format!("{}", out));
assert_eq!( assert_eq!(out, Idiom(vec![Part::from("test")]));
out,
Idiom {
parts: vec![Part::from("test")],
}
);
} }
#[test] #[test]
@ -169,12 +159,7 @@ mod tests {
assert!(res.is_ok()); assert!(res.is_ok());
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("test", format!("{}", out)); assert_eq!("test", format!("{}", out));
assert_eq!( assert_eq!(out, Idiom(vec![Part::from("test")]));
out,
Idiom {
parts: vec![Part::from("test")],
}
);
} }
#[test] #[test]
@ -184,12 +169,7 @@ mod tests {
assert!(res.is_ok()); assert!(res.is_ok());
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("test", format!("{}", out)); assert_eq!("test", format!("{}", out));
assert_eq!( assert_eq!(out, Idiom(vec![Part::from("test")]));
out,
Idiom {
parts: vec![Part::from("test")],
}
);
} }
#[test] #[test]
@ -199,12 +179,7 @@ mod tests {
assert!(res.is_ok()); assert!(res.is_ok());
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("test.temp", format!("{}", out)); assert_eq!("test.temp", format!("{}", out));
assert_eq!( assert_eq!(out, Idiom(vec![Part::from("test"), Part::from("temp"),]));
out,
Idiom {
parts: vec![Part::from("test"), Part::from("temp"),],
}
);
} }
#[test] #[test]
@ -214,12 +189,7 @@ mod tests {
assert!(res.is_ok()); assert!(res.is_ok());
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("test.`some key`", format!("{}", out)); assert_eq!("test.`some key`", format!("{}", out));
assert_eq!( assert_eq!(out, Idiom(vec![Part::from("test"), Part::from("some key"),]));
out,
Idiom {
parts: vec![Part::from("test"), Part::from("some key"),],
}
);
} }
#[test] #[test]
@ -229,12 +199,7 @@ mod tests {
assert!(res.is_ok()); assert!(res.is_ok());
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("test.temp[*]", format!("{}", out)); assert_eq!("test.temp[*]", format!("{}", out));
assert_eq!( assert_eq!(out, Idiom(vec![Part::from("test"), Part::from("temp"), Part::All,]));
out,
Idiom {
parts: vec![Part::from("test"), Part::from("temp"), Part::All,],
}
);
} }
#[test] #[test]
@ -244,12 +209,7 @@ mod tests {
assert!(res.is_ok()); assert!(res.is_ok());
let out = res.unwrap().1; let out = res.unwrap().1;
assert_eq!("test.temp[$]", format!("{}", out)); assert_eq!("test.temp[$]", format!("{}", out));
assert_eq!( assert_eq!(out, Idiom(vec![Part::from("test"), Part::from("temp"), Part::Last,]));
out,
Idiom {
parts: vec![Part::from("test"), Part::from("temp"), Part::Last,],
}
);
} }
#[test] #[test]
@ -261,9 +221,7 @@ mod tests {
assert_eq!("test.temp[*].text", format!("{}", out)); assert_eq!("test.temp[*].text", format!("{}", out));
assert_eq!( assert_eq!(
out, out,
Idiom { Idiom(vec![Part::from("test"), Part::from("temp"), Part::All, Part::from("text")])
parts: vec![Part::from("test"), Part::from("temp"), Part::All, Part::from("text")],
}
); );
} }
@ -276,14 +234,12 @@ mod tests {
assert_eq!("test.temp[WHERE test = true].text", format!("{}", out)); assert_eq!("test.temp[WHERE test = true].text", format!("{}", out));
assert_eq!( assert_eq!(
out, out,
Idiom { Idiom(vec![
parts: vec![
Part::from("test"), Part::from("test"),
Part::from("temp"), Part::from("temp"),
Part::from(Value::from(Expression::parse("test = true"))), Part::from(Value::from(Expression::parse("test = true"))),
Part::from("text") Part::from("text")
], ])
}
); );
} }
@ -296,14 +252,12 @@ mod tests {
assert_eq!("test.temp[WHERE test = true].text", format!("{}", out)); assert_eq!("test.temp[WHERE test = true].text", format!("{}", out));
assert_eq!( assert_eq!(
out, out,
Idiom { Idiom(vec![
parts: vec![
Part::from("test"), Part::from("test"),
Part::from("temp"), Part::from("temp"),
Part::from(Value::from(Expression::parse("test = true"))), Part::from(Value::from(Expression::parse("test = true"))),
Part::from("text") Part::from("text")
], ])
}
); );
} }
} }

View file

@ -39,7 +39,7 @@ impl Param {
doc: Option<&Value>, doc: Option<&Value>,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
// Find a base variable by name // Find a base variable by name
match self.parts.first() { match self.first() {
// The first part will be a field // The first part will be a field
Some(Part::Field(v)) => match v.as_str() { Some(Part::Field(v)) => match v.as_str() {
"this" => match doc { "this" => match doc {