wip,fix: tests, lang errors

feat/type-attributes
Tomáš Mládek 2023-06-29 12:58:06 +02:00
parent a591db0cd4
commit f880a0e38c
4 changed files with 44 additions and 61 deletions

15
Cargo.lock generated
View File

@ -3215,7 +3215,7 @@ dependencies = [
"serde",
"shadow-rs",
"url",
"uuid 1.4.0",
"uuid",
"wasm-bindgen",
]
@ -3272,7 +3272,7 @@ dependencies = [
"upend-base",
"upend-db",
"url",
"uuid 0.8.2",
"uuid",
"walkdir",
"webbrowser",
"webp",
@ -3309,7 +3309,7 @@ dependencies = [
"tree_magic_mini",
"upend-base",
"url",
"uuid 1.4.0",
"uuid",
"walkdir",
]
@ -3363,15 +3363,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
dependencies = [
"getrandom 0.2.9",
]
[[package]]
name = "uuid"
version = "1.4.0"

View File

@ -4,6 +4,7 @@ pub enum UpEndError {
AddressParseError(String),
AddressComponentsDecodeError(AddressComponentsDecodeError),
CannotSerializeInvalid,
QueryParseError(String),
Other(String),
}
@ -32,6 +33,7 @@ impl std::fmt::Display for UpEndError {
},
UpEndError::CannotSerializeInvalid =>
String::from("Invalid EntryValues cannot be serialized."),
UpEndError::QueryParseError(err) => format!("Error parsing query: {err}"),
UpEndError::Other(err) => format!("Unknown error: {err}"),
}
)

View File

@ -34,7 +34,7 @@ pub struct PatternQuery {
}
impl TryFrom<lexpr::Value> for Address {
type Error = QueryParseError;
type Error = UpEndError;
fn try_from(value: lexpr::Value) -> Result<Self, Self::Error> {
match value {
@ -42,14 +42,14 @@ impl TryFrom<lexpr::Value> for Address {
if let Some(address_str) = str.strip_prefix('@') {
address_str
.parse()
.map_err(|e: UpEndError| QueryParseError(e.to_string()))
.map_err(|e: UpEndError| UpEndError::QueryParseError(e.to_string()))
} else {
Err(QueryParseError(
Err(UpEndError::QueryParseError(
"Incorrect address format (use @address).".into(),
))
}
}
_ => Err(QueryParseError(
_ => Err(UpEndError::QueryParseError(
"Incorrect type for address (use @address).".into(),
)),
}
@ -57,19 +57,17 @@ impl TryFrom<lexpr::Value> for Address {
}
impl TryFrom<lexpr::Value> for EntryValue {
type Error = QueryParseError;
type Error = UpEndError;
fn try_from(value: lexpr::Value) -> Result<Self, Self::Error> {
match value {
lexpr::Value::Number(num) => {
Ok(EntryValue::Number(num.as_f64().ok_or_else(|| {
QueryParseError(format!("Error processing number ({num:?})."))
})?))
}
lexpr::Value::Number(num) => Ok(EntryValue::Number(num.as_f64().ok_or_else(|| {
UpEndError::QueryParseError(format!("Error processing number ({num:?})."))
})?)),
lexpr::Value::Char(chr) => Ok(EntryValue::String(chr.to_string())),
lexpr::Value::String(str) => Ok(EntryValue::String(str.to_string())),
lexpr::Value::Symbol(_) => Ok(EntryValue::Address(Address::try_from(value.clone())?)),
_ => Err(QueryParseError(
_ => Err(UpEndError::QueryParseError(
"Value can only be a string, number or address.".into(),
)),
}
@ -77,12 +75,12 @@ impl TryFrom<lexpr::Value> for EntryValue {
}
impl TryFrom<lexpr::Value> for Attribute {
type Error = QueryParseError;
type Error = UpEndError;
fn try_from(value: lexpr::Value) -> Result<Self, Self::Error> {
match value {
lexpr::Value::String(str) => Ok(Attribute(str.to_string())),
_ => Err(QueryParseError(
_ => Err(UpEndError::QueryParseError(
"Can only convert to attribute from string.".into(),
)),
}
@ -116,26 +114,15 @@ pub enum Query {
MultiQuery(MultiQuery),
}
#[derive(Debug, Clone)]
pub struct QueryParseError(String);
impl std::fmt::Display for QueryParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::error::Error for QueryParseError {}
impl TryFrom<&lexpr::Value> for Query {
type Error = QueryParseError;
type Error = UpEndError;
fn try_from(expression: &lexpr::Value) -> Result<Self, Self::Error> {
fn parse_component<T: TryFrom<lexpr::Value>>(
value: &lexpr::Value,
) -> Result<QueryComponent<T>, QueryParseError>
) -> Result<QueryComponent<T>, UpEndError>
where
QueryParseError: From<<T as TryFrom<lexpr::Value>>::Error>,
UpEndError: From<<T as TryFrom<lexpr::Value>>::Error>,
{
match value {
lexpr::Value::Cons(cons) => {
@ -152,7 +139,7 @@ impl TryFrom<&lexpr::Value> for Query {
Ok(QueryComponent::In(values?))
} else {
Err(QueryParseError(
Err(UpEndError::QueryParseError(
"Malformed expression: Inner value cannot be empty.".into(),
))
}
@ -165,21 +152,21 @@ impl TryFrom<&lexpr::Value> for Query {
if let lexpr::Value::String(str) = value {
Ok(QueryComponent::Contains(str.into_string()))
} else {
Err(QueryParseError("Malformed expression: 'Contains' argument must be a string.".into()))
Err(UpEndError::QueryParseError("Malformed expression: 'Contains' argument must be a string.".into()))
}
}
_ => Err(QueryParseError(
_ => Err(UpEndError::QueryParseError(
"Malformed expression: 'Contains' requires a single argument.".into()
)),
}
}
_ => Err(QueryParseError(format!(
_ => Err(UpEndError::QueryParseError(format!(
"Malformed expression: Unknown symbol {}",
symbol
))),
}
} else {
Err(QueryParseError(format!(
Err(UpEndError::QueryParseError(format!(
"Malformed expression: Inner value '{:?}' is not a symbol.",
value
)))
@ -212,7 +199,7 @@ impl TryFrom<&lexpr::Value> for Query {
value,
})))
} else {
Err(QueryParseError(
Err(UpEndError::QueryParseError(
"Malformed expression: Wrong number of arguments to 'matches'."
.into(),
))
@ -226,13 +213,13 @@ impl TryFrom<&lexpr::Value> for Query {
type_name_str.to_string(),
)))
} else {
Err(QueryParseError(
Err(UpEndError::QueryParseError(
"Malformed expression: Type must be specified as a string."
.into(),
))
}
} else {
Err(QueryParseError(
Err(UpEndError::QueryParseError(
"Malformed expression: Wrong number of arguments to 'type'.".into(),
))
}
@ -243,7 +230,7 @@ impl TryFrom<&lexpr::Value> for Query {
let values = sub_expressions
.iter()
.map(|value| Ok(Box::new(Query::try_from(value)?)))
.collect::<Result<Vec<Box<Query>>, QueryParseError>>()?;
.collect::<Result<Vec<Box<Query>>, UpEndError>>()?;
if let Some(queries) = NonEmpty::from_vec(values) {
Ok(Query::MultiQuery(MultiQuery {
@ -255,7 +242,7 @@ impl TryFrom<&lexpr::Value> for Query {
queries,
}))
} else {
Err(QueryParseError(
Err(UpEndError::QueryParseError(
"Malformed expression: sub-query list cannot be empty.".into(),
))
}
@ -266,7 +253,7 @@ impl TryFrom<&lexpr::Value> for Query {
let values = sub_expressions
.iter()
.map(|value| Ok(Box::new(Query::try_from(value)?)))
.collect::<Result<Vec<Box<Query>>, QueryParseError>>()?;
.collect::<Result<Vec<Box<Query>>, UpEndError>>()?;
if values.len() == 1 {
Ok(Query::MultiQuery(MultiQuery {
@ -274,34 +261,37 @@ impl TryFrom<&lexpr::Value> for Query {
queries: NonEmpty::from_vec(values).unwrap(),
}))
} else {
Err(QueryParseError(
Err(UpEndError::QueryParseError(
"Malformed expression: NOT takes exactly one parameter.".into(),
))
}
}
_ => Err(QueryParseError(format!(
_ => Err(UpEndError::QueryParseError(format!(
"Malformed expression: Unknown symbol '{}'.",
symbol
))),
}
} else {
Err(QueryParseError(format!(
Err(UpEndError::QueryParseError(format!(
"Malformed expression: Value '{:?}' is not a symbol.",
value
)))
}
} else {
Err(QueryParseError("Malformed expression: Not a list.".into()))
Err(UpEndError::QueryParseError(
"Malformed expression: Not a list.".into(),
))
}
}
}
impl FromStr for Query {
type Err = QueryParseError;
type Err = UpEndError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let sexp = lexpr::from_str_custom(s, lexpr::parse::Options::new())
.map_err(|e| QueryParseError(format!("failed to parse s-expression: {e}")))?;
let sexp = lexpr::from_str_custom(s, lexpr::parse::Options::new()).map_err(|e| {
UpEndError::QueryParseError(format!("failed to parse s-expression: {e}"))
})?;
Query::try_from(&sexp)
}
}
@ -361,7 +351,7 @@ mod test {
}
#[test]
fn test_joins() -> Result<()> {
fn test_joins() -> Result<(), UpEndError> {
let query = "(matches ?a ?b ?)".parse::<Query>()?;
assert_eq!(
query,
@ -376,7 +366,7 @@ mod test {
}
#[test]
fn test_in_parse() -> Result<()> {
fn test_in_parse() -> Result<(), UpEndError> {
let query = r#"(matches ? (in "FOO" "BAR") ?)"#.parse::<Query>()?;
assert_eq!(
query,
@ -438,7 +428,7 @@ mod test {
}
#[test]
fn test_contains() -> Result<()> {
fn test_contains() -> Result<(), UpEndError> {
let query = r#"(matches (contains "foo") ? ?)"#.parse::<Query>()?;
assert_eq!(
query,

View File

@ -55,7 +55,7 @@ multihash = { version = "*", default-features = false, features = [
"sha2",
"identity",
] }
uuid = { version = "0.8", features = ["v4"] }
uuid = { version = "1.4", features = ["v4"] }
filebuffer = "0.4.0"
tempfile = "^3.2.0"