From 7175784356887da4a998d6fef01ad2edbfcb9025 Mon Sep 17 00:00:00 2001 From: Tpt Date: Sat, 29 Apr 2023 11:51:50 +0200 Subject: [PATCH] Improves Clippy lint list --- .cargo/config.toml | 68 ++++-- js/src/model.rs | 2 +- js/src/store.rs | 8 +- lib/oxrdf/src/dataset.rs | 4 +- lib/oxrdf/src/interning.rs | 9 +- lib/oxrdf/src/lib.rs | 1 - lib/oxsdatatypes/src/decimal.rs | 2 +- lib/oxsdatatypes/src/duration.rs | 6 +- lib/oxsdatatypes/src/integer.rs | 10 +- lib/oxsdatatypes/src/lib.rs | 2 +- lib/sparesults/src/csv.rs | 14 +- lib/sparesults/src/lib.rs | 4 +- lib/sparesults/src/solution.rs | 3 +- lib/sparesults/src/xml.rs | 22 +- lib/spargebra/src/lib.rs | 1 - lib/spargebra/src/parser.rs | 19 +- lib/src/io/error.rs | 12 +- lib/src/lib.rs | 2 +- lib/src/sparql/dataset.rs | 2 +- lib/src/sparql/eval.rs | 366 +++++++++++++--------------- lib/src/sparql/model.rs | 7 +- lib/src/sparql/plan.rs | 26 +- lib/src/sparql/plan_builder.rs | 165 ++++++------- lib/src/sparql/update.rs | 17 +- lib/src/storage/backend/fallback.rs | 27 +- lib/src/storage/backend/rocksdb.rs | 60 ++--- lib/src/storage/mod.rs | 5 +- lib/src/store.rs | 4 +- lib/tests/store.rs | 2 +- python/src/io.rs | 12 +- python/src/sparql.rs | 2 +- python/src/store.rs | 8 +- server/src/main.rs | 6 +- testsuite/src/manifest.rs | 2 +- testsuite/src/sparql_evaluator.rs | 26 +- 35 files changed, 457 insertions(+), 469 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index be86f8ae..e248c473 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,94 +2,124 @@ rustflags = [ "-Wtrivial-casts", "-Wtrivial-numeric-casts", - "-Wunsafe_code", + "-Wunsafe-code", "-Wunused-lifetimes", "-Wunused-qualifications", + # TODO: 1.63+ "-Wclippy::as-underscore", + # TODO: 1.65+ ""-Wclippy::bool-to-int-with-if", + "-Wclippy::borrow-as-ptr", + "-Wclippy::case-sensitive-file-extension-comparisons", "-Wclippy::cast-lossless", "-Wclippy::cast-possible-truncation", "-Wclippy::cast-possible-wrap", "-Wclippy::cast-precision-loss", + "-Wclippy::cast-ptr-alignment", "-Wclippy::cast-sign-loss", "-Wclippy::checked-conversions", + "-Wclippy::clone-on-ref-ptr", "-Wclippy::cloned-instead-of-copied", "-Wclippy::copy-iterator", "-Wclippy::dbg-macro", - "-Wclippy::debug-assert-with-mut-call", "-Wclippy::decimal-literal-representation", - "-Wclippy::empty-line-after-outer-attr", + "-Wclippy::default-trait-access", + "-Wclippy::default-union-representation", + # TODO: 1.61+ "-Wclippy::deref-by-slicing", + # TODO: 1.63+ "-Wclippy::doc-link-with-quotes", + # TODO: 1.62+ "-Wclippy::empty-drop", "-Wclippy::empty-enum", + # TODO: on major version "-Wclippy::empty-structs-with-brackets", "-Wclippy::enum-glob-use", + "-Wclippy::exit", "-Wclippy::expect-used", "-Wclippy::expl-impl-clone-on-copy", "-Wclippy::explicit-deref-methods", "-Wclippy::explicit-into-iter-loop", "-Wclippy::explicit-iter-loop", - "-Wclippy::fallible-impl-from", "-Wclippy::filter-map-next", "-Wclippy::flat-map-option", + "-Wclippy::fn-to-numeric-cast-any", + # TODO: 1.62+ "-Wclippy::format-push-string", "-Wclippy::from-iter-instead-of-collect", "-Wclippy::get-unwrap", "-Wclippy::if-not-else", + "-Wclippy::if-then-some-else-none", "-Wclippy::implicit-clone", - "-Wclippy::implicit-saturating-sub", - "-Wclippy::imprecise-flops", "-Wclippy::inconsistent-struct-constructor", + "-Wclippy::index-refutable-slice", "-Wclippy::inefficient-to-string", "-Wclippy::inline-always", + "-Wclippy::inline-asm-x86-att-syntax", + "-Wclippy::inline-asm-x86-intel-syntax", "-Wclippy::invalid-upcast-comparisons", "-Wclippy::items-after-statements", "-Wclippy::large-digit-groups", + # TODO: 1.68+ "-Wclippy::large-futures", "-Wclippy::large-stack-arrays", "-Wclippy::large-types-passed-by-value", "-Wclippy::let-underscore-must-use", "-Wclippy::let-unit-value", "-Wclippy::linkedlist", + "-Wclippy::lossy-float-literal", "-Wclippy::macro-use-imports", + "-Wclippy::manual-assert", + # TODO: 1.65+ "-Wclippy::manual-instant-elapsed", + # TODO: 1.67+ "-Wclippy::manual-let-else", "-Wclippy::manual-ok-or", - "-Wclippy::map-flatten", + # TODO: 1.65+ "-Wclippy::manual-string-new", + "-Wclippy::many-single-char-names", "-Wclippy::map-unwrap-or", "-Wclippy::match-bool", "-Wclippy::match-same-arms", "-Wclippy::match-wildcard-for-single-variants", "-Wclippy::maybe-infinite-iter", "-Wclippy::mem-forget", + # TODO: 1.63+ "-Wclippy::mismatching-type-param-order", "-Wclippy::multiple-inherent-impl", "-Wclippy::mut-mut", - "-Wclippy::mutex-integer", + "-Wclippy::mutex-atomic", "-Wclippy::naive-bytecount", "-Wclippy::needless-bitwise-bool", "-Wclippy::needless-continue", "-Wclippy::needless-pass-by-value", + "-Wclippy::no-effect-underscore-binding", + # TODO: 1.69+ "-Wclippy::no-mangle-with-rust-abi", "-Wclippy::non-ascii-literal", - "-Wclippy::nonstandard-macro-braces", - "-Wclippy::path-buf-push-overwrite", "-Wclippy::print-stderr", "-Wclippy::print-stdout", + "-Wclippy::ptr-as-ptr", "-Wclippy::range-minus-one", "-Wclippy::range-plus-one", + "-Wclippy::rc-buffer", "-Wclippy::rc-mutex", - "-Wclippy::enum-variant-names", + "-Wclippy::redundant-closure-for-method-calls", "-Wclippy::redundant-else", - "-Wclippy::redundant-pub-crate", + "-Wclippy::redundant-feature-names", "-Wclippy::ref-binding-to-reference", "-Wclippy::ref-option-ref", "-Wclippy::rest-pat-in-fully-bound-structs", + "-Wclippy::return-self-not-must-use", "-Wclippy::same-functions-in-if-condition", + # TODO: strange failure on 1.60 "-Wclippy::same-name-method", + # TODO: 1.68+ "-Wclippy::semicolon-outside-block", + "-Wclippy::single-match-else", + "-Wclippy::stable-sort-primitive", "-Wclippy::str-to-string", "-Wclippy::string-add", "-Wclippy::string-add-assign", "-Wclippy::string-lit-as-bytes", "-Wclippy::string-to-string", - "-Wclippy::suboptimal-flops", - "-Wclippy::suspicious-operation-groupings", + # TODO: 1.67+ "-Wclippy::suspicious-xor-used-as-pow", "-Wclippy::todo", - "-Wclippy::trait-duplication-in-bounds", "-Wclippy::transmute-ptr-to-ptr", - "-Wclippy::trivial-regex", "-Wclippy::trivially-copy-pass-by-ref", - "-Wclippy::type-repetition-in-bounds", + "-Wclippy::try-err", "-Wclippy::unicode-not-nfc", "-Wclippy::unimplemented", + # TODO: 1.66+ "-Wclippy::uninlined-format-args", + # TODO: 1.70+ "-Wclippy::unnecessary-box-returns", + # TODO: 1.61+ "-Wclippy::unnecessary-join", + # TODO: 1.67+ "-Wclippy::unnecessary-safety-comment", + # TODO: 1.67+ "-Wclippy::unnecessary-safety-doc", "-Wclippy::unnecessary-self-imports", "-Wclippy::unnecessary-wraps", "-Wclippy::unneeded-field-pattern", @@ -99,13 +129,9 @@ rustflags = [ "-Wclippy::unused-async", "-Wclippy::unused-self", "-Wclippy::use-debug", - "-Wclippy::use-self", "-Wclippy::used-underscore-binding", - "-Wclippy::useless-let-if-seq", - "-Wclippy::useless-transmute", "-Wclippy::verbose-bit-mask", "-Wclippy::verbose-file-reads", "-Wclippy::wildcard-dependencies", "-Wclippy::zero-sized-map-values", - "-Wclippy::wrong-self-convention", ] \ No newline at end of file diff --git a/js/src/model.rs b/js/src/model.rs index 179dafce..4929068f 100644 --- a/js/src/model.rs +++ b/js/src/model.rs @@ -19,7 +19,7 @@ thread_local! { #[wasm_bindgen(js_name = namedNode)] pub fn named_node(value: String) -> Result { NamedNode::new(value) - .map(|v| v.into()) + .map(Into::into) .map_err(|v| UriError::new(&v.to_string()).into()) } diff --git a/js/src/store.rs b/js/src/store.rs index 13b3f6b3..adee6eef 100644 --- a/js/src/store.rs +++ b/js/src/store.rs @@ -76,28 +76,28 @@ impl JsStore { None } .as_ref() - .map(|t: &NamedOrBlankNode| t.into()), + .map(<&Subject>::into), if let Some(predicate) = FROM_JS.with(|c| c.to_optional_term(predicate))? { Some(NamedNode::try_from(predicate)?) } else { None } .as_ref() - .map(|t: &NamedNode| t.into()), + .map(<&NamedNode>::into), if let Some(object) = FROM_JS.with(|c| c.to_optional_term(object))? { Some(object.try_into()?) } else { None } .as_ref() - .map(|t: &Term| t.into()), + .map(<&Term>::into), if let Some(graph_name) = FROM_JS.with(|c| c.to_optional_term(graph_name))? { Some(graph_name.try_into()?) } else { None } .as_ref() - .map(|t: &GraphName| t.into()), + .map(<&GraphName>::into), ) .map(|v| v.map(|v| JsQuad::from(v).into())) .collect::, _>>() diff --git a/lib/oxrdf/src/dataset.rs b/lib/oxrdf/src/dataset.rs index 12d07880..9925f7ca 100644 --- a/lib/oxrdf/src/dataset.rs +++ b/lib/oxrdf/src/dataset.rs @@ -705,9 +705,7 @@ impl Dataset { InternedTerm, InternedGraphName, )> { - let b_prime = partition - .iter() - .find_map(|(_, b)| if b.len() > 1 { Some(b) } else { None }); + let b_prime = partition.iter().find_map(|(_, b)| (b.len() > 1).then(|| b)); if let Some(b_prime) = b_prime { b_prime .iter() diff --git a/lib/oxrdf/src/interning.rs b/lib/oxrdf/src/interning.rs index 41725dca..54c8acde 100644 --- a/lib/oxrdf/src/interning.rs +++ b/lib/oxrdf/src/interning.rs @@ -463,11 +463,10 @@ impl InternedTriple { predicate: InternedNamedNode::encoded_from(triple.predicate, interner)?, object: InternedTerm::encoded_from(triple.object, interner)?, }; - if interner.triples.contains_key(&interned_triple) { - Some(interned_triple) - } else { - None - } + interner + .triples + .contains_key(&interned_triple) + .then(|| interned_triple) } pub fn next(&self) -> Self { diff --git a/lib/oxrdf/src/lib.rs b/lib/oxrdf/src/lib.rs index 9d40ead4..aa6f712b 100644 --- a/lib/oxrdf/src/lib.rs +++ b/lib/oxrdf/src/lib.rs @@ -1,5 +1,4 @@ #![doc = include_str!("../README.md")] -#![deny(unsafe_code)] #![doc(test(attr(deny(warnings))))] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc(html_favicon_url = "https://raw.githubusercontent.com/oxigraph/oxigraph/main/logo.svg")] diff --git a/lib/oxsdatatypes/src/decimal.rs b/lib/oxsdatatypes/src/decimal.rs index 3b49e229..c7fa6ba9 100644 --- a/lib/oxsdatatypes/src/decimal.rs +++ b/lib/oxsdatatypes/src/decimal.rs @@ -380,7 +380,7 @@ impl FromStr for Decimal { }; let mut value = 0_i128; - let with_before_dot = input.first().map_or(false, |c| c.is_ascii_digit()); + let with_before_dot = input.first().map_or(false, u8::is_ascii_digit); while let Some(c) = input.first() { if c.is_ascii_digit() { value = value diff --git a/lib/oxsdatatypes/src/duration.rs b/lib/oxsdatatypes/src/duration.rs index 27f255eb..18d42912 100644 --- a/lib/oxsdatatypes/src/duration.rs +++ b/lib/oxsdatatypes/src/duration.rs @@ -170,8 +170,10 @@ impl fmt::Display for Duration { let h = (s_int % 86400) / 3600; let m = (s_int % 3600) / 60; let s = ss - .checked_sub(Decimal::try_from(d * 86400 + h * 3600 + m * 60).unwrap()) - .unwrap(); //could not fail + .checked_sub( + Decimal::try_from(d * 86400 + h * 3600 + m * 60).map_err(|_| fmt::Error)?, + ) + .ok_or(fmt::Error)?; if d != 0 { write!(f, "{d}D")?; diff --git a/lib/oxsdatatypes/src/integer.rs b/lib/oxsdatatypes/src/integer.rs index 50f2d002..016096b3 100644 --- a/lib/oxsdatatypes/src/integer.rs +++ b/lib/oxsdatatypes/src/integer.rs @@ -258,9 +258,9 @@ mod tests { assert!(Integer::try_from(Float::from(f32::MIN)).is_err()); assert!(Integer::try_from(Float::from(f32::MAX)).is_err()); assert!( - Integer::try_from(Float::from(1_672_507_302_466.)) + Integer::try_from(Float::from(1_672_507_300_000.)) .unwrap() - .checked_sub(Integer::from_str("1672507302466")?) + .checked_sub(Integer::from_str("1672507300000")?) .unwrap() .abs() < Integer::from(1_000_000) @@ -283,12 +283,12 @@ mod tests { Some(Integer::from_str("-123")?) ); assert!( - Integer::try_from(Double::from(1_672_507_302_466.)) + Integer::try_from(Double::from(1_672_507_300_000.)) .unwrap() - .checked_sub(Integer::from_str("1672507302466").unwrap()) + .checked_sub(Integer::from_str("1672507300000").unwrap()) .unwrap() .abs() - < Integer::from(1) + < Integer::from(10) ); assert!(Integer::try_from(Double::from(f64::NAN)).is_err()); assert!(Integer::try_from(Double::from(f64::INFINITY)).is_err()); diff --git a/lib/oxsdatatypes/src/lib.rs b/lib/oxsdatatypes/src/lib.rs index 7c06ca9e..67737b13 100644 --- a/lib/oxsdatatypes/src/lib.rs +++ b/lib/oxsdatatypes/src/lib.rs @@ -1,9 +1,9 @@ #![doc = include_str!("../README.md")] -#![deny(unsafe_code)] #![doc(test(attr(deny(warnings))))] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc(html_favicon_url = "https://raw.githubusercontent.com/oxigraph/oxigraph/main/logo.svg")] #![doc(html_logo_url = "https://raw.githubusercontent.com/oxigraph/oxigraph/main/logo.svg")] +#![allow(clippy::return_self_not_must_use)] mod boolean; mod date_time; diff --git a/lib/sparesults/src/csv.rs b/lib/sparesults/src/csv.rs index 14991fe6..b365c4ac 100644 --- a/lib/sparesults/src/csv.rs +++ b/lib/sparesults/src/csv.rs @@ -160,7 +160,7 @@ fn write_tsv_term<'a>(term: impl Into>, sink: &mut impl Write) -> io let value = literal.value(); if let Some(language) = literal.language() { write_tsv_quoted_str(value, sink)?; - write!(sink, "@{}", language) + write!(sink, "@{language}") } else { match literal.datatype() { xsd::BOOLEAN if is_turtle_boolean(value) => sink.write_all(value.as_bytes()), @@ -216,7 +216,7 @@ fn is_turtle_integer(value: &str) -> bool { } else if let Some(v) = value.strip_prefix(b"-") { value = v; } - !value.is_empty() && value.iter().all(|c| c.is_ascii_digit()) + !value.is_empty() && value.iter().all(u8::is_ascii_digit) } fn is_turtle_decimal(value: &str) -> bool { @@ -227,7 +227,7 @@ fn is_turtle_decimal(value: &str) -> bool { } else if let Some(v) = value.strip_prefix(b"-") { value = v; } - while value.first().map_or(false, |c| c.is_ascii_digit()) { + while value.first().map_or(false, u8::is_ascii_digit) { value = &value[1..]; } if let Some(v) = value.strip_prefix(b".") { @@ -235,7 +235,7 @@ fn is_turtle_decimal(value: &str) -> bool { } else { return false; } - !value.is_empty() && value.iter().all(|c| c.is_ascii_digit()) + !value.is_empty() && value.iter().all(u8::is_ascii_digit) } fn is_turtle_double(value: &str) -> bool { @@ -248,14 +248,14 @@ fn is_turtle_double(value: &str) -> bool { value = v; } let mut with_before = false; - while value.first().map_or(false, |c| c.is_ascii_digit()) { + while value.first().map_or(false, u8::is_ascii_digit) { value = &value[1..]; with_before = true; } let mut with_after = false; if let Some(v) = value.strip_prefix(b".") { value = v; - while value.first().map_or(false, |c| c.is_ascii_digit()) { + while value.first().map_or(false, u8::is_ascii_digit) { value = &value[1..]; with_after = true; } @@ -272,7 +272,7 @@ fn is_turtle_double(value: &str) -> bool { } else if let Some(v) = value.strip_prefix(b"-") { value = v; } - (with_before || with_after) && !value.is_empty() && value.iter().all(|c| c.is_ascii_digit()) + (with_before || with_after) && !value.is_empty() && value.iter().all(u8::is_ascii_digit) } pub enum TsvQueryResultsReader { diff --git a/lib/sparesults/src/lib.rs b/lib/sparesults/src/lib.rs index dc9a3075..b30c17f0 100644 --- a/lib/sparesults/src/lib.rs +++ b/lib/sparesults/src/lib.rs @@ -1,5 +1,4 @@ #![doc = include_str!("../README.md")] -#![deny(unsafe_code)] #![doc(test(attr(deny(warnings))))] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc(html_favicon_url = "https://raw.githubusercontent.com/oxigraph/oxigraph/main/logo.svg")] @@ -276,6 +275,7 @@ pub enum QueryResultsReader { /// } /// # Result::<(),sparesults::ParseError>::Ok(()) /// ``` +#[allow(clippy::rc_buffer)] pub struct SolutionsReader { variables: Rc>, solutions: SolutionsReaderKind, @@ -318,7 +318,7 @@ impl Iterator for SolutionsReader { SolutionsReaderKind::Tsv(reader) => reader.read_next(), } .transpose()? - .map(|values| (self.variables.clone(), values).into()), + .map(|values| (Rc::clone(&self.variables), values).into()), ) } } diff --git a/lib/sparesults/src/solution.rs b/lib/sparesults/src/solution.rs index b1be7c7d..a8059204 100644 --- a/lib/sparesults/src/solution.rs +++ b/lib/sparesults/src/solution.rs @@ -18,6 +18,7 @@ use std::rc::Rc; /// assert_eq!(solution.get("foo"), Some(&Literal::from(1).into())); // Get the value of the variable ?foo if it exists (here yes). /// assert_eq!(solution.get(1), None); // Get the value of the second column if it exists (here no). /// ``` +#[allow(clippy::rc_buffer)] pub struct QuerySolution { variables: Rc>, values: Vec>, @@ -69,7 +70,7 @@ impl QuerySolution { /// ``` #[inline] pub fn is_empty(&self) -> bool { - self.values.iter().all(|v| v.is_none()) + self.values.iter().all(Option::is_none) } /// Returns an iterator over bound variables. diff --git a/lib/sparesults/src/xml.rs b/lib/sparesults/src/xml.rs index fd0ed3b4..d493e7d9 100644 --- a/lib/sparesults/src/xml.rs +++ b/lib/sparesults/src/xml.rs @@ -482,20 +482,31 @@ impl XmlSolutionsReader { } state = State::Triple; } - State::Uri => state = self.stack.pop().unwrap(), + State::Uri => { + state = self + .stack + .pop() + .ok_or_else(|| SyntaxError::msg("Empty stack"))? + } State::BNode => { if term.is_none() { //We default to a random bnode term = Some(BlankNode::default().into()) } - state = self.stack.pop().unwrap() + state = self + .stack + .pop() + .ok_or_else(|| SyntaxError::msg("Empty stack"))? } State::Literal => { if term.is_none() { //We default to the empty literal term = Some(build_literal("", lang.take(), datatype.take())?.into()) } - state = self.stack.pop().unwrap(); + state = self + .stack + .pop() + .ok_or_else(|| SyntaxError::msg("Empty stack"))?; } State::Triple => { #[cfg(feature = "rdf-star")] @@ -530,7 +541,10 @@ impl XmlSolutionsReader { ) .into(), ); - state = self.stack.pop().unwrap(); + state = self + .stack + .pop() + .ok_or_else(|| SyntaxError::msg("Empty stack"))?; } else { return Err( SyntaxError::msg("A should contain a , a and an ").into() diff --git a/lib/spargebra/src/lib.rs b/lib/spargebra/src/lib.rs index dc0e2aa7..e2d093f3 100644 --- a/lib/spargebra/src/lib.rs +++ b/lib/spargebra/src/lib.rs @@ -1,5 +1,4 @@ #![doc = include_str!("../README.md")] -#![deny(unsafe_code)] #![doc(test(attr(deny(warnings))))] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc(html_favicon_url = "https://raw.githubusercontent.com/oxigraph/oxigraph/main/logo.svg")] diff --git a/lib/spargebra/src/parser.rs b/lib/spargebra/src/parser.rs index 689b95ce..0f85b830 100644 --- a/lib/spargebra/src/parser.rs +++ b/lib/spargebra/src/parser.rs @@ -352,7 +352,7 @@ impl> From> for FocusedTripleOrPathPattern fn from(input: FocusedTriplePattern) -> Self { Self { focus: input.focus.into(), - patterns: input.patterns.into_iter().map(|p| p.into()).collect(), + patterns: input.patterns.into_iter().map(Into::into).collect(), } } } @@ -736,7 +736,7 @@ impl ParserState { let aggregates = self.aggregates.last_mut().ok_or("Unexpected aggregate")?; Ok(aggregates .iter() - .find_map(|(v, a)| if a == &agg { Some(v) } else { None }) + .find_map(|(v, a)| (a == &agg).then(|| v)) .cloned() .unwrap_or_else(|| { let new_var = variable(); @@ -884,13 +884,14 @@ impl<'a> Iterator for UnescapeCharsIterator<'a> { } match self.iter.next()? { '\\' => match self.iter.next() { - Some(ch) => match self.replacement.get(ch) { - Some(replace) => Some(replace), - None => { + Some(ch) => { + if let Some(replace) = self.replacement.get(ch) { + Some(replace) + } else { self.buffer = Some(ch); Some('\\') } - }, + } None => Some('\\'), }, c => Some(c), @@ -1590,7 +1591,7 @@ parser! { //[74] rule ConstructTriples() -> Vec = p:ConstructTriples_item() ** ("." _) "."? { - p.into_iter().flat_map(|c| c.into_iter()).collect() + p.into_iter().flatten().collect() } rule ConstructTriples_item() -> Vec = t:TriplesSameSubject() _ { t } @@ -1701,7 +1702,7 @@ parser! { //[83] rule PropertyListPathNotEmpty() -> FocusedTripleOrPathPattern)>> = hp:(VerbPath() / VerbSimple()) _ ho:ObjectListPath() _ t:PropertyListPathNotEmpty_item()* { - t.into_iter().flat_map(|e| e.into_iter()).fold(FocusedTripleOrPathPattern { + t.into_iter().flatten().fold(FocusedTripleOrPathPattern { focus: vec![(hp, ho.focus)], patterns: ho.patterns }, |mut a, b| { @@ -2036,7 +2037,7 @@ parser! { //[121] rule BuiltInCall() -> Expression = - a:Aggregate() {? state.new_aggregation(a).map(|v| v.into()) } / + a:Aggregate() {? state.new_aggregation(a).map(Into::into) } / i("STR") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Str, vec![e]) } / i("LANG") _ "(" _ e:Expression() _ ")" { Expression::FunctionCall(Function::Lang, vec![e]) } / i("LANGMATCHES") _ "(" _ a:Expression() _ "," _ b:Expression() _ ")" { Expression::FunctionCall(Function::LangMatches, vec![a, b]) } / diff --git a/lib/src/io/error.rs b/lib/src/io/error.rs index 5584169b..6a90404b 100644 --- a/lib/src/io/error.rs +++ b/lib/src/io/error.rs @@ -45,12 +45,14 @@ impl Error for ParseError { } } -#[allow(clippy::fallible_impl_from)] impl From for ParseError { #[inline] fn from(error: TurtleError) -> Self { let error = io::Error::from(error); - if error.get_ref().map_or(false, |e| e.is::()) { + if error.get_ref().map_or( + false, + <(dyn Error + Send + Sync + 'static)>::is::, + ) { Self::Syntax(SyntaxError { inner: SyntaxErrorKind::Turtle(*error.into_inner().unwrap().downcast().unwrap()), }) @@ -60,12 +62,14 @@ impl From for ParseError { } } -#[allow(clippy::fallible_impl_from)] impl From for ParseError { #[inline] fn from(error: RdfXmlError) -> Self { let error = io::Error::from(error); - if error.get_ref().map_or(false, |e| e.is::()) { + if error.get_ref().map_or( + false, + <(dyn Error + Send + Sync + 'static)>::is::, + ) { Self::Syntax(SyntaxError { inner: SyntaxErrorKind::RdfXml(*error.into_inner().unwrap().downcast().unwrap()), }) diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 2b67f0c9..29ef24ae 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -3,7 +3,7 @@ #![doc(html_logo_url = "https://raw.githubusercontent.com/oxigraph/oxigraph/main/logo.svg")] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc(test(attr(deny(warnings))))] -#![deny(unsafe_code)] +#![allow(clippy::return_self_not_must_use)] pub mod io; pub mod sparql; diff --git a/lib/src/sparql/dataset.rs b/lib/src/sparql/dataset.rs index 75191258..bf7e6195 100644 --- a/lib/src/sparql/dataset.rs +++ b/lib/src/sparql/dataset.rs @@ -40,7 +40,7 @@ impl DatasetView { ) -> impl Iterator> + 'static { self.reader .quads_for_pattern(subject, predicate, object, graph_name) - .map(|t| t.map_err(|e| e.into())) + .map(|t| t.map_err(Into::into)) } #[allow(clippy::needless_collect)] diff --git a/lib/src/sparql/eval.rs b/lib/src/sparql/eval.rs index a71b95cb..3650e2d0 100644 --- a/lib/src/sparql/eval.rs +++ b/lib/src/sparql/eval.rs @@ -65,6 +65,7 @@ impl SimpleEvaluator { } } + #[allow(clippy::rc_buffer)] pub fn evaluate_select_plan( &self, plan: Rc, @@ -73,7 +74,7 @@ impl SimpleEvaluator { let (eval, stats) = self.plan_evaluator(plan); ( QueryResults::Solutions(decode_bindings( - self.dataset.clone(), + Rc::clone(&self.dataset), eval(EncodedTuple::with_capacity(variables.len())), variables, )), @@ -164,16 +165,16 @@ impl SimpleEvaluator { graph_pattern, .. } => { - let variables = variables.clone(); + let variables = Rc::clone(variables); let silent = *silent; let service_name = service_name.clone(); - let graph_pattern = graph_pattern.clone(); + let graph_pattern = Rc::clone(graph_pattern); let eval = self.clone(); Rc::new(move |from| { match eval.evaluate_service( &service_name, &graph_pattern, - variables.clone(), + Rc::clone(&variables), &from, ) { Ok(result) => Box::new(result.filter_map(move |binding| { @@ -201,7 +202,7 @@ impl SimpleEvaluator { let predicate = TupleSelector::from(predicate); let object = TupleSelector::from(object); let graph_name = TupleSelector::from(graph_name); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |from| { let iter = dataset.encoded_quads_for_pattern( get_pattern_value(&subject, &from).as_ref(), @@ -233,16 +234,16 @@ impl SimpleEvaluator { graph_name, } => { let subject = TupleSelector::from(subject); - let path = path.clone(); + let path = Rc::clone(path); let object = TupleSelector::from(object); let graph_name = TupleSelector::from(graph_name); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |from| { let input_subject = get_pattern_value(&subject, &from); let input_object = get_pattern_value(&object, &from); let input_graph_name = get_pattern_value(&graph_name, &from); let path_eval = PathEvaluator { - dataset: dataset.clone(), + dataset: Rc::clone(&dataset), }; match (input_subject, input_object, input_graph_name) { (Some(input_subject), Some(input_object), Some(input_graph_name)) => { @@ -384,9 +385,9 @@ impl SimpleEvaluator { .intersection(&right.always_bound_variables()) .copied() .collect(); - let (left, left_stats) = self.plan_evaluator(left.clone()); + let (left, left_stats) = self.plan_evaluator(Rc::clone(left)); stat_children.push(left_stats); - let (right, right_stats) = self.plan_evaluator(right.clone()); + let (right, right_stats) = self.plan_evaluator(Rc::clone(right)); stat_children.push(right_stats); if join_keys.is_empty() { // Cartesian product @@ -430,12 +431,12 @@ impl SimpleEvaluator { } } PlanNode::ForLoopJoin { left, right } => { - let (left, left_stats) = self.plan_evaluator(left.clone()); + let (left, left_stats) = self.plan_evaluator(Rc::clone(left)); stat_children.push(left_stats); - let (right, right_stats) = self.plan_evaluator(right.clone()); + let (right, right_stats) = self.plan_evaluator(Rc::clone(right)); stat_children.push(right_stats); Rc::new(move |from| { - let right = right.clone(); + let right = Rc::clone(&right); Box::new(left(from).flat_map(move |t| match t { Ok(t) => right(t), Err(e) => Box::new(once(Err(e))), @@ -448,9 +449,9 @@ impl SimpleEvaluator { .intersection(&right.always_bound_variables()) .copied() .collect(); - let (left, left_stats) = self.plan_evaluator(left.clone()); + let (left, left_stats) = self.plan_evaluator(Rc::clone(left)); stat_children.push(left_stats); - let (right, right_stats) = self.plan_evaluator(right.clone()); + let (right, right_stats) = self.plan_evaluator(Rc::clone(right)); stat_children.push(right_stats); if join_keys.is_empty() { Rc::new(move |from| { @@ -491,9 +492,9 @@ impl SimpleEvaluator { .intersection(&right.always_bound_variables()) .copied() .collect(); - let (left, left_stats) = self.plan_evaluator(left.clone()); + let (left, left_stats) = self.plan_evaluator(Rc::clone(left)); stat_children.push(left_stats); - let (right, right_stats) = self.plan_evaluator(right.clone()); + let (right, right_stats) = self.plan_evaluator(Rc::clone(right)); stat_children.push(right_stats); let expression = self.expression_evaluator(expression, &mut stat_children); // Real hash join @@ -511,7 +512,7 @@ impl SimpleEvaluator { left_iter: left(from), right: right_values, buffered_results: errors, - expression: expression.clone(), + expression: Rc::clone(&expression), }) }) } @@ -520,36 +521,36 @@ impl SimpleEvaluator { right, possible_problem_vars, } => { - let (left, left_stats) = self.plan_evaluator(left.clone()); + let (left, left_stats) = self.plan_evaluator(Rc::clone(left)); stat_children.push(left_stats); - let (right, right_stats) = self.plan_evaluator(right.clone()); + let (right, right_stats) = self.plan_evaluator(Rc::clone(right)); stat_children.push(right_stats); - let possible_problem_vars = possible_problem_vars.clone(); + let possible_problem_vars = Rc::clone(possible_problem_vars); Rc::new(move |from| { if possible_problem_vars.is_empty() { Box::new(ForLoopLeftJoinIterator { - right_evaluator: right.clone(), + right_evaluator: Rc::clone(&right), left_iter: left(from), current_right: Box::new(empty()), }) } else { Box::new(BadForLoopLeftJoinIterator { from_tuple: from.clone(), - right_evaluator: right.clone(), + right_evaluator: Rc::clone(&right), left_iter: left(from), - current_left: None, + current_left: EncodedTuple::with_capacity(0), current_right: Box::new(empty()), - problem_vars: possible_problem_vars.clone(), + problem_vars: Rc::clone(&possible_problem_vars), }) } }) } PlanNode::Filter { child, expression } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); let expression = self.expression_evaluator(expression, &mut stat_children); Rc::new(move |from| { - let expression = expression.clone(); + let expression = Rc::clone(&expression); Box::new(child(from).filter(move |tuple| { match tuple { Ok(tuple) => expression(tuple) @@ -564,7 +565,7 @@ impl SimpleEvaluator { let children: Vec<_> = children .iter() .map(|child| { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); child }) @@ -583,12 +584,12 @@ impl SimpleEvaluator { variable, expression, } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); let position = variable.encoded; let expression = self.expression_evaluator(expression, &mut stat_children); Rc::new(move |from| { - let expression = expression.clone(); + let expression = Rc::clone(&expression); Box::new(child(from).map(move |tuple| { let mut tuple = tuple?; if let Some(value) = expression(&tuple) { @@ -599,7 +600,7 @@ impl SimpleEvaluator { }) } PlanNode::Sort { child, by } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); let by: Vec<_> = by .iter() @@ -612,7 +613,7 @@ impl SimpleEvaluator { ), }) .collect(); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |from| { let mut errors = Vec::default(); let mut values = child(from) @@ -657,12 +658,12 @@ impl SimpleEvaluator { }) } PlanNode::HashDeduplicate { child } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); Rc::new(move |from| Box::new(hash_deduplicate(child(from)))) } PlanNode::Reduced { child } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); Rc::new(move |from| { Box::new(ConsecutiveDeduplication { @@ -672,23 +673,23 @@ impl SimpleEvaluator { }) } PlanNode::Skip { child, count } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); let count = *count; Rc::new(move |from| Box::new(child(from).skip(count))) } PlanNode::Limit { child, count } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); let count = *count; Rc::new(move |from| Box::new(child(from).take(count))) } PlanNode::Project { child, mapping } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); - let mapping = mapping.clone(); + let mapping = Rc::clone(mapping); Rc::new(move |from| { - let mapping = mapping.clone(); + let mapping = Rc::clone(&mapping); let mut input_tuple = EncodedTuple::with_capacity(mapping.len()); for (input_key, output_key) in mapping.iter() { if let Some(value) = from.get(output_key.encoded) { @@ -724,9 +725,9 @@ impl SimpleEvaluator { key_variables, aggregates, } => { - let (child, child_stats) = self.plan_evaluator(child.clone()); + let (child, child_stats) = self.plan_evaluator(Rc::clone(child)); stat_children.push(child_stats); - let key_variables = key_variables.clone(); + let key_variables = Rc::clone(key_variables); let aggregate_input_expressions: Vec<_> = aggregates .iter() .map(|(aggregate, _)| { @@ -750,7 +751,7 @@ impl SimpleEvaluator { aggregates.iter().map(|(_, var)| var.encoded).collect(); Rc::new(move |from| { let tuple_size = from.capacity(); - let key_variables = key_variables.clone(); + let key_variables = Rc::clone(&key_variables); let mut errors = Vec::default(); let mut accumulators_for_group = HashMap::>, Vec>>::default(); @@ -825,7 +826,7 @@ impl SimpleEvaluator { exec_duration: Cell::new(std::time::Duration::from_secs(0)), }); if self.run_stats { - let stats = stats.clone(); + let stats = Rc::clone(&stats); evaluator = Rc::new(move |tuple| { let start = Timer::now(); let inner = evaluator(tuple); @@ -834,7 +835,7 @@ impl SimpleEvaluator { .set(stats.exec_duration.get() + start.elapsed()); Box::new(StatsIterator { inner, - stats: stats.clone(), + stats: Rc::clone(&stats), }) }) } @@ -845,7 +846,7 @@ impl SimpleEvaluator { &self, service_name: &PatternValue, graph_pattern: &GraphPattern, - variables: Rc>, + variables: Rc<[Variable]>, from: &EncodedTuple, ) -> Result { let service_name = get_pattern_value(&service_name.into(), from) @@ -862,7 +863,7 @@ impl SimpleEvaluator { parsing_duration: None, }, )? { - Ok(encode_bindings(self.dataset.clone(), variables, iter)) + Ok(encode_bindings(Rc::clone(&self.dataset), variables, iter)) } else { Err(EvaluationError::msg( "The service call has not returned a set of solutions", @@ -892,12 +893,12 @@ impl SimpleEvaluator { } } PlanAggregationFunction::Min => { - let dataset = dataset.clone(); - Box::new(move || Box::new(MinAccumulator::new(dataset.clone()))) + let dataset = Rc::clone(dataset); + Box::new(move || Box::new(MinAccumulator::new(Rc::clone(&dataset)))) } // DISTINCT does not make sense with min PlanAggregationFunction::Max => { - let dataset = dataset.clone(); - Box::new(move || Box::new(MaxAccumulator::new(dataset.clone()))) + let dataset = Rc::clone(dataset); + Box::new(move || Box::new(MaxAccumulator::new(Rc::clone(&dataset)))) } // DISTINCT does not make sense with max PlanAggregationFunction::Avg => { if distinct { @@ -908,20 +909,20 @@ impl SimpleEvaluator { } PlanAggregationFunction::Sample => Box::new(|| Box::::default()), // DISTINCT does not make sense with sample PlanAggregationFunction::GroupConcat { separator } => { - let dataset = dataset.clone(); - let separator = separator.clone(); + let dataset = Rc::clone(dataset); + let separator = Rc::clone(separator); if distinct { Box::new(move || { Box::new(DistinctAccumulator::new(GroupConcatAccumulator::new( - dataset.clone(), - separator.clone(), + Rc::clone(&dataset), + Rc::clone(&separator), ))) }) } else { Box::new(move || { Box::new(GroupConcatAccumulator::new( - dataset.clone(), - separator.clone(), + Rc::clone(&dataset), + Rc::clone(&separator), )) }) } @@ -949,7 +950,7 @@ impl SimpleEvaluator { Rc::new(move |tuple| tuple.get(v).cloned()) } PlanExpression::Exists(plan) => { - let (eval, stats) = self.plan_evaluator(plan.clone()); + let (eval, stats) = self.plan_evaluator(Rc::clone(plan)); stat_children.push(stats); Rc::new(move |tuple| Some(eval(tuple.clone()).next().is_some().into())) } @@ -959,13 +960,7 @@ impl SimpleEvaluator { Rc::new(move |tuple| match a(tuple).and_then(|v| to_bool(&v)) { Some(true) => Some(true.into()), Some(false) => b(tuple), - None => { - if Some(true) == a(tuple).and_then(|v| to_bool(&v)) { - Some(true.into()) - } else { - None - } - } + None => (Some(true) == a(tuple).and_then(|v| to_bool(&v))).then(|| true.into()), }) } PlanExpression::And(a, b) => { @@ -975,23 +970,19 @@ impl SimpleEvaluator { Some(true) => b(tuple), Some(false) => Some(false.into()), None => { - if Some(false) == b(tuple).and_then(|v| to_bool(&v)) { - Some(false.into()) - } else { - None - } + (Some(false) == b(tuple).and_then(|v| to_bool(&v))).then(|| false.into()) } }) } PlanExpression::Equal(a, b) => { let a = self.expression_evaluator(a, stat_children); let b = self.expression_evaluator(b, stat_children); - Rc::new(move |tuple| equals(&a(tuple)?, &b(tuple)?).map(|v| v.into())) + Rc::new(move |tuple| equals(&a(tuple)?, &b(tuple)?).map(Into::into)) } PlanExpression::Greater(a, b) => { let a = self.expression_evaluator(a, stat_children); let b = self.expression_evaluator(b, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some( (partial_cmp(&dataset, &a(tuple)?, &b(tuple)?)? == Ordering::Greater) @@ -1002,7 +993,7 @@ impl SimpleEvaluator { PlanExpression::GreaterOrEqual(a, b) => { let a = self.expression_evaluator(a, stat_children); let b = self.expression_evaluator(b, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some( match partial_cmp(&dataset, &a(tuple)?, &b(tuple)?)? { @@ -1016,7 +1007,7 @@ impl SimpleEvaluator { PlanExpression::Less(a, b) => { let a = self.expression_evaluator(a, stat_children); let b = self.expression_evaluator(b, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some((partial_cmp(&dataset, &a(tuple)?, &b(tuple)?)? == Ordering::Less).into()) }) @@ -1024,7 +1015,7 @@ impl SimpleEvaluator { PlanExpression::LessOrEqual(a, b) => { let a = self.expression_evaluator(a, stat_children); let b = self.expression_evaluator(b, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some( match partial_cmp(&dataset, &a(tuple)?, &b(tuple)?)? { @@ -1191,7 +1182,7 @@ impl SimpleEvaluator { } PlanExpression::Str(e) | PlanExpression::StringCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some(build_string_literal_from_id(to_string_id( &dataset, @@ -1201,7 +1192,7 @@ impl SimpleEvaluator { } PlanExpression::Lang(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::SmallSmallLangStringLiteral { language, .. } | EncodedTerm::BigSmallLangStringLiteral { language, .. } => { @@ -1218,7 +1209,7 @@ impl SimpleEvaluator { PlanExpression::LangMatches(language_tag, language_range) => { let language_tag = self.expression_evaluator(language_tag, stat_children); let language_range = self.expression_evaluator(language_range, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let mut language_tag = to_simple_string(&dataset, &language_tag(tuple)?)?; language_tag.make_ascii_lowercase(); @@ -1243,7 +1234,7 @@ impl SimpleEvaluator { } PlanExpression::Datatype(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| datatype(&dataset, &e(tuple)?)) } PlanExpression::Bound(v) => { @@ -1252,7 +1243,7 @@ impl SimpleEvaluator { } PlanExpression::Iri(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); let base_iri = self.base_iri.clone(); Rc::new(move |tuple| { let e = e(tuple)?; @@ -1276,7 +1267,7 @@ impl SimpleEvaluator { PlanExpression::BNode(id) => match id { Some(id) => { let id = self.expression_evaluator(id, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some( dataset.encode_term( @@ -1339,7 +1330,7 @@ impl SimpleEvaluator { .iter() .map(|e| self.expression_evaluator(e, stat_children)) .collect(); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let mut result = String::default(); let mut language = None; @@ -1367,7 +1358,7 @@ impl SimpleEvaluator { let length = length .as_ref() .map(|l| self.expression_evaluator(l, stat_children)); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (source, language) = to_string_and_language(&dataset, &source(tuple)?)?; @@ -1411,7 +1402,7 @@ impl SimpleEvaluator { } PlanExpression::StrLen(arg) => { let arg = self.expression_evaluator(arg, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some((to_string(&dataset, &arg(tuple)?)?.chars().count() as i64).into()) }) @@ -1420,7 +1411,7 @@ impl SimpleEvaluator { let arg = self.expression_evaluator(arg, stat_children); let regex = regex.clone(); let replacement = self.expression_evaluator(replacement, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (text, language) = to_string_and_language(&dataset, &arg(tuple)?)?; let replacement = to_simple_string(&dataset, &replacement(tuple)?)?; @@ -1438,7 +1429,7 @@ impl SimpleEvaluator { let flags = flags .as_ref() .map(|flags| self.expression_evaluator(flags, stat_children)); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let pattern = to_simple_string(&dataset, &pattern(tuple)?)?; let options = if let Some(flags) = &flags { @@ -1458,7 +1449,7 @@ impl SimpleEvaluator { } PlanExpression::UCase(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (value, language) = to_string_and_language(&dataset, &e(tuple)?)?; Some(build_plain_literal( @@ -1470,7 +1461,7 @@ impl SimpleEvaluator { } PlanExpression::LCase(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (value, language) = to_string_and_language(&dataset, &e(tuple)?)?; Some(build_plain_literal( @@ -1483,7 +1474,7 @@ impl SimpleEvaluator { PlanExpression::StrStarts(arg1, arg2) => { let arg1 = self.expression_evaluator(arg1, stat_children); let arg2 = self.expression_evaluator(arg2, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (arg1, arg2, _) = to_argument_compatible_strings(&dataset, &arg1(tuple)?, &arg2(tuple)?)?; @@ -1492,7 +1483,7 @@ impl SimpleEvaluator { } PlanExpression::EncodeForUri(ltrl) => { let ltrl = self.expression_evaluator(ltrl, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let ltlr = to_string(&dataset, <rl(tuple)?)?; let mut result = Vec::with_capacity(ltlr.len()); @@ -1527,7 +1518,7 @@ impl SimpleEvaluator { PlanExpression::StrEnds(arg1, arg2) => { let arg1 = self.expression_evaluator(arg1, stat_children); let arg2 = self.expression_evaluator(arg2, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (arg1, arg2, _) = to_argument_compatible_strings(&dataset, &arg1(tuple)?, &arg2(tuple)?)?; @@ -1537,7 +1528,7 @@ impl SimpleEvaluator { PlanExpression::Contains(arg1, arg2) => { let arg1 = self.expression_evaluator(arg1, stat_children); let arg2 = self.expression_evaluator(arg2, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (arg1, arg2, _) = to_argument_compatible_strings(&dataset, &arg1(tuple)?, &arg2(tuple)?)?; @@ -1547,7 +1538,7 @@ impl SimpleEvaluator { PlanExpression::StrBefore(arg1, arg2) => { let arg1 = self.expression_evaluator(arg1, stat_children); let arg2 = self.expression_evaluator(arg2, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (arg1, arg2, language) = to_argument_compatible_strings(&dataset, &arg1(tuple)?, &arg2(tuple)?)?; @@ -1561,7 +1552,7 @@ impl SimpleEvaluator { PlanExpression::StrAfter(arg1, arg2) => { let arg1 = self.expression_evaluator(arg1, stat_children); let arg2 = self.expression_evaluator(arg2, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let (arg1, arg2, language) = to_argument_compatible_strings(&dataset, &arg1(tuple)?, &arg2(tuple)?)?; @@ -1648,7 +1639,7 @@ impl SimpleEvaluator { } PlanExpression::Tz(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let timezone_offset = match e(tuple)? { EncodedTerm::DateTimeLiteral(date_time) => date_time.timezone_offset(), @@ -1706,7 +1697,7 @@ impl SimpleEvaluator { Rc::new(move |_| Some(now.into())) } PlanExpression::Uuid => { - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |_| { let mut buffer = String::with_capacity(44); buffer.push_str("urn:uuid:"); @@ -1715,7 +1706,7 @@ impl SimpleEvaluator { }) } PlanExpression::StrUuid => { - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |_| { let mut buffer = String::with_capacity(36); generate_uuid(&mut buffer); @@ -1756,7 +1747,7 @@ impl SimpleEvaluator { PlanExpression::StrLang(lexical_form, lang_tag) => { let lexical_form = self.expression_evaluator(lexical_form, stat_children); let lang_tag = self.expression_evaluator(lang_tag, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { Some(build_lang_string_literal_from_id( to_simple_string_id(&lexical_form(tuple)?)?, @@ -1767,7 +1758,7 @@ impl SimpleEvaluator { PlanExpression::StrDt(lexical_form, datatype) => { let lexical_form = self.expression_evaluator(lexical_form, stat_children); let datatype = self.expression_evaluator(datatype, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let value = to_simple_string(&dataset, &lexical_form(tuple)?)?; let datatype = if let EncodedTerm::NamedNode { iri_id } = datatype(tuple)? { @@ -1815,7 +1806,7 @@ impl SimpleEvaluator { } PlanExpression::StaticRegex(text, regex) => { let text = self.expression_evaluator(text, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); let regex = regex.clone(); Rc::new(move |tuple| { let text = to_string(&dataset, &text(tuple)?)?; @@ -1828,7 +1819,7 @@ impl SimpleEvaluator { let flags = flags .as_ref() .map(|flags| self.expression_evaluator(flags, stat_children)); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let pattern = to_simple_string(&dataset, &pattern(tuple)?)?; let options = if let Some(flags) = &flags { @@ -1849,15 +1840,11 @@ impl SimpleEvaluator { let s = s(tuple)?; let p = p(tuple)?; let o = o(tuple)?; - if !s.is_literal() + (!s.is_literal() && !s.is_default_graph() && p.is_named_node() - && !o.is_default_graph() - { - Some(EncodedTriple::new(s, p, o).into()) - } else { - None - } + && !o.is_default_graph()) + .then(|| EncodedTriple::new(s, p, o).into()) }) } PlanExpression::Subject(e) => { @@ -1908,7 +1895,7 @@ impl SimpleEvaluator { } PlanExpression::DoubleCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::FloatLiteral(value) => Some(Double::from(value).into()), EncodedTerm::DoubleLiteral(value) => Some(value.into()), @@ -1924,7 +1911,7 @@ impl SimpleEvaluator { } PlanExpression::FloatCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::FloatLiteral(value) => Some(value.into()), EncodedTerm::DoubleLiteral(value) => Some(Float::from(value).into()), @@ -1940,7 +1927,7 @@ impl SimpleEvaluator { } PlanExpression::IntegerCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::FloatLiteral(value) => Some(Integer::try_from(value).ok()?.into()), EncodedTerm::DoubleLiteral(value) => { @@ -1960,7 +1947,7 @@ impl SimpleEvaluator { } PlanExpression::DecimalCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::FloatLiteral(value) => Some(Decimal::try_from(value).ok()?.into()), EncodedTerm::DoubleLiteral(value) => { @@ -1980,7 +1967,7 @@ impl SimpleEvaluator { } PlanExpression::DateCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::DateLiteral(value) => Some(value.into()), EncodedTerm::DateTimeLiteral(value) => Some(Date::try_from(value).ok()?.into()), @@ -1993,7 +1980,7 @@ impl SimpleEvaluator { } PlanExpression::TimeCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::TimeLiteral(value) => Some(value.into()), EncodedTerm::DateTimeLiteral(value) => Some(Time::try_from(value).ok()?.into()), @@ -2006,7 +1993,7 @@ impl SimpleEvaluator { } PlanExpression::DateTimeCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::DateTimeLiteral(value) => Some(value.into()), EncodedTerm::DateLiteral(value) => Some(DateTime::try_from(value).ok()?.into()), @@ -2019,7 +2006,7 @@ impl SimpleEvaluator { } PlanExpression::DurationCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::DurationLiteral(value) => Some(value.into()), EncodedTerm::YearMonthDurationLiteral(value) => { @@ -2037,7 +2024,7 @@ impl SimpleEvaluator { } PlanExpression::YearMonthDurationCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::DurationLiteral(value) => { Some(YearMonthDuration::try_from(value).ok()?.into()) @@ -2052,7 +2039,7 @@ impl SimpleEvaluator { } PlanExpression::DayTimeDurationCast(e) => { let e = self.expression_evaluator(e, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| match e(tuple)? { EncodedTerm::DurationLiteral(value) => { Some(DayTimeDuration::try_from(value).ok()?.into()) @@ -2071,7 +2058,7 @@ impl SimpleEvaluator { .iter() .map(|e| self.expression_evaluator(e, stat_children)) .collect::>(); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let args = args .iter() @@ -2092,7 +2079,7 @@ impl SimpleEvaluator { stat_children: &mut Vec>, ) -> Rc Option> { let arg = self.expression_evaluator(arg, stat_children); - let dataset = self.dataset.clone(); + let dataset = Rc::clone(&self.dataset); Rc::new(move |tuple| { let input = to_simple_string(&dataset, &arg(tuple)?)?; let hash = hex::encode(H::new().chain_update(input.as_str()).finalize()); @@ -2305,11 +2292,7 @@ fn to_argument_compatible_strings( ) -> Option<(String, String, Option)> { let (value1, language1) = to_string_and_language(dataset, arg1)?; let (value2, language2) = to_string_and_language(dataset, arg2)?; - if language2.is_none() || language1 == language2 { - Some((value1, value2, language1)) - } else { - None - } + (language2.is_none() || language1 == language2).then(|| (value1, value2, language1)) } pub(super) fn compile_pattern(pattern: &str, flags: Option<&str>) -> Option { @@ -2337,6 +2320,7 @@ pub(super) fn compile_pattern(pattern: &str, flags: Option<&str>) -> Option, iter: EncodedTuplesIterator, @@ -2360,7 +2344,7 @@ fn decode_bindings( // this is used to encode results from a BindingIterator into an EncodedTuplesIterator. This happens when SERVICE clauses are evaluated fn encode_bindings( dataset: Rc, - variables: Rc>, + variables: Rc<[Variable]>, iter: QuerySolutionIter, ) -> EncodedTuplesIterator { Box::new(iter.map(move |solution| { @@ -3074,20 +3058,10 @@ fn put_pattern_value( tuple: &mut EncodedTuple, ) -> Option<()> { match selector { - TupleSelector::Constant(c) => { - if *c == value { - Some(()) - } else { - None - } - } + TupleSelector::Constant(c) => (*c == value).then(|| ()), TupleSelector::Variable(v) => { if let Some(old) = tuple.get(*v) { - if value == *old { - Some(()) - } else { - None - } + (value == *old).then(|| ()) } else { tuple.set(*v, value); Some(()) @@ -3163,11 +3137,9 @@ impl PathEvaluator { .find_map(|middle| { middle .and_then(|middle| { - Ok(if self.eval_closed_in_graph(b, &middle, end, graph_name)? { - Some(()) - } else { - None - }) + Ok(self + .eval_closed_in_graph(b, &middle, end, graph_name)? + .then(|| ())) }) .transpose() }) @@ -3233,12 +3205,12 @@ impl PathEvaluator { PlanPropertyPath::Reverse(p) => self.eval_closed_in_unknown_graph(p, end, start), PlanPropertyPath::Sequence(a, b) => { let eval = self.clone(); - let b = b.clone(); + let b = Rc::clone(b); let end = end.clone(); Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok( move |(middle, graph_name)| { eval.eval_closed_in_graph(&b, &middle, &end, &graph_name) - .map(|is_found| if is_found { Some(graph_name) } else { None }) + .map(|is_found| is_found.then(|| graph_name)) .transpose() }, )) @@ -3251,21 +3223,21 @@ impl PathEvaluator { let eval = self.clone(); let start2 = start.clone(); let end = end.clone(); - let p = p.clone(); + let p = Rc::clone(p); self.run_if_term_is_a_dataset_node(start, move |graph_name| { look_in_transitive_closure( Some(Ok(start2.clone())), |e| eval.eval_from_in_graph(&p, &e, &graph_name), &end, ) - .map(|is_found| if is_found { Some(graph_name) } else { None }) + .map(|is_found| is_found.then(|| graph_name)) .transpose() }) } PlanPropertyPath::OneOrMore(p) => { let eval = self.clone(); let end = end.clone(); - let p = p.clone(); + let p = Rc::clone(p); Box::new( self.eval_from_in_unknown_graph(&p, start) .filter_map(move |r| { @@ -3275,13 +3247,7 @@ impl PathEvaluator { |e| eval.eval_from_in_graph(&p, &e, &graph_name), &end, ) - .map(|is_found| { - if is_found { - Some(graph_name) - } else { - None - } - }) + .map(|is_found| is_found.then(|| graph_name)) }) .transpose() }), @@ -3294,16 +3260,16 @@ impl PathEvaluator { let eval = self.clone(); let start2 = start.clone(); let end = end.clone(); - let p = p.clone(); + let p = Rc::clone(p); self.run_if_term_is_a_dataset_node(start, move |graph_name| { eval.eval_closed_in_graph(&p, &start2, &end, &graph_name) - .map(|is_found| if is_found { Some(graph_name) } else { None }) + .map(|is_found| is_found.then(|| graph_name)) .transpose() }) } } PlanPropertyPath::NegatedPropertySet(ps) => { - let ps = ps.clone(); + let ps = Rc::clone(ps); Box::new( self.dataset .encoded_quads_for_pattern(Some(start), None, Some(end), None) @@ -3342,7 +3308,7 @@ impl PathEvaluator { PlanPropertyPath::Reverse(p) => self.eval_to_in_graph(p, start, graph_name), PlanPropertyPath::Sequence(a, b) => { let eval = self.clone(); - let b = b.clone(); + let b = Rc::clone(b); let graph_name2 = graph_name.clone(); Box::new( self.eval_from_in_graph(a, start, graph_name) @@ -3358,7 +3324,7 @@ impl PathEvaluator { PlanPropertyPath::ZeroOrMore(p) => { self.run_if_term_is_a_graph_node(start, graph_name, || { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); let graph_name2 = graph_name.clone(); transitive_closure(Some(Ok(start.clone())), move |e| { eval.eval_from_in_graph(&p, &e, &graph_name2) @@ -3367,7 +3333,7 @@ impl PathEvaluator { } PlanPropertyPath::OneOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); let graph_name2 = graph_name.clone(); Box::new(transitive_closure( self.eval_from_in_graph(&p, start, graph_name), @@ -3383,7 +3349,7 @@ impl PathEvaluator { }) } PlanPropertyPath::NegatedPropertySet(ps) => { - let ps = ps.clone(); + let ps = Rc::clone(ps); Box::new( self.dataset .encoded_quads_for_pattern(Some(start), None, None, Some(graph_name)) @@ -3419,7 +3385,7 @@ impl PathEvaluator { PlanPropertyPath::Reverse(p) => self.eval_to_in_unknown_graph(p, start), PlanPropertyPath::Sequence(a, b) => { let eval = self.clone(); - let b = b.clone(); + let b = Rc::clone(b); Box::new(self.eval_from_in_unknown_graph(a, start).flat_map_ok( move |(middle, graph_name)| { eval.eval_from_in_graph(&b, &middle, &graph_name) @@ -3434,10 +3400,10 @@ impl PathEvaluator { PlanPropertyPath::ZeroOrMore(p) => { let start2 = start.clone(); let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); self.run_if_term_is_a_dataset_node(start, move |graph_name| { let eval = eval.clone(); - let p = p.clone(); + let p = Rc::clone(&p); let graph_name2 = graph_name.clone(); transitive_closure(Some(Ok(start2.clone())), move |e| { eval.eval_from_in_graph(&p, &e, &graph_name2) @@ -3447,7 +3413,7 @@ impl PathEvaluator { } PlanPropertyPath::OneOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); Box::new(transitive_closure( self.eval_from_in_unknown_graph(&p, start), move |(e, graph_name)| { @@ -3459,7 +3425,7 @@ impl PathEvaluator { PlanPropertyPath::ZeroOrOne(p) => { let eval = self.clone(); let start2 = start.clone(); - let p = p.clone(); + let p = Rc::clone(p); self.run_if_term_is_a_dataset_node(start, move |graph_name| { hash_deduplicate(once(Ok(start2.clone())).chain(eval.eval_from_in_graph( &p, @@ -3470,7 +3436,7 @@ impl PathEvaluator { }) } PlanPropertyPath::NegatedPropertySet(ps) => { - let ps = ps.clone(); + let ps = Rc::clone(ps); Box::new( self.dataset .encoded_quads_for_pattern(Some(start), None, None, None) @@ -3504,7 +3470,7 @@ impl PathEvaluator { PlanPropertyPath::Reverse(p) => self.eval_from_in_graph(p, end, graph_name), PlanPropertyPath::Sequence(a, b) => { let eval = self.clone(); - let a = a.clone(); + let a = Rc::clone(a); let graph_name2 = graph_name.clone(); Box::new( self.eval_to_in_graph(b, end, graph_name) @@ -3520,7 +3486,7 @@ impl PathEvaluator { PlanPropertyPath::ZeroOrMore(p) => { self.run_if_term_is_a_graph_node(end, graph_name, || { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); let graph_name2 = graph_name.clone(); transitive_closure(Some(Ok(end.clone())), move |e| { eval.eval_to_in_graph(&p, &e, &graph_name2) @@ -3529,7 +3495,7 @@ impl PathEvaluator { } PlanPropertyPath::OneOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); let graph_name2 = graph_name.clone(); Box::new(transitive_closure( self.eval_to_in_graph(&p, end, graph_name), @@ -3544,7 +3510,7 @@ impl PathEvaluator { }) } PlanPropertyPath::NegatedPropertySet(ps) => { - let ps = ps.clone(); + let ps = Rc::clone(ps); Box::new( self.dataset .encoded_quads_for_pattern(None, None, Some(end), Some(graph_name)) @@ -3579,7 +3545,7 @@ impl PathEvaluator { PlanPropertyPath::Reverse(p) => self.eval_from_in_unknown_graph(p, end), PlanPropertyPath::Sequence(a, b) => { let eval = self.clone(); - let a = a.clone(); + let a = Rc::clone(a); Box::new(self.eval_to_in_unknown_graph(b, end).flat_map_ok( move |(middle, graph_name)| { eval.eval_from_in_graph(&a, &middle, &graph_name) @@ -3594,10 +3560,10 @@ impl PathEvaluator { PlanPropertyPath::ZeroOrMore(p) => { let end2 = end.clone(); let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); self.run_if_term_is_a_dataset_node(end, move |graph_name| { let eval = eval.clone(); - let p = p.clone(); + let p = Rc::clone(&p); let graph_name2 = graph_name.clone(); transitive_closure(Some(Ok(end2.clone())), move |e| { eval.eval_to_in_graph(&p, &e, &graph_name2) @@ -3607,7 +3573,7 @@ impl PathEvaluator { } PlanPropertyPath::OneOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); Box::new(transitive_closure( self.eval_to_in_unknown_graph(&p, end), move |(e, graph_name)| { @@ -3619,7 +3585,7 @@ impl PathEvaluator { PlanPropertyPath::ZeroOrOne(p) => { let eval = self.clone(); let end2 = end.clone(); - let p = p.clone(); + let p = Rc::clone(p); self.run_if_term_is_a_dataset_node(end, move |graph_name| { hash_deduplicate(once(Ok(end2.clone())).chain(eval.eval_to_in_graph( &p, @@ -3630,7 +3596,7 @@ impl PathEvaluator { }) } PlanPropertyPath::NegatedPropertySet(ps) => { - let ps = ps.clone(); + let ps = Rc::clone(ps); Box::new( self.dataset .encoded_quads_for_pattern(Some(end), None, None, None) @@ -3666,7 +3632,7 @@ impl PathEvaluator { ), PlanPropertyPath::Sequence(a, b) => { let eval = self.clone(); - let b = b.clone(); + let b = Rc::clone(b); let graph_name2 = graph_name.clone(); Box::new(self.eval_open_in_graph(a, graph_name).flat_map_ok( move |(start, middle)| { @@ -3681,7 +3647,7 @@ impl PathEvaluator { )), PlanPropertyPath::ZeroOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); let graph_name2 = graph_name.clone(); Box::new(transitive_closure( self.get_subject_or_object_identity_pairs_in_graph(graph_name), @@ -3693,7 +3659,7 @@ impl PathEvaluator { } PlanPropertyPath::OneOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); let graph_name2 = graph_name.clone(); Box::new(transitive_closure( self.eval_open_in_graph(&p, graph_name), @@ -3708,7 +3674,7 @@ impl PathEvaluator { .chain(self.eval_open_in_graph(p, graph_name)), )), PlanPropertyPath::NegatedPropertySet(ps) => { - let ps = ps.clone(); + let ps = Rc::clone(ps); Box::new( self.dataset .encoded_quads_for_pattern(None, None, None, Some(graph_name)) @@ -3744,7 +3710,7 @@ impl PathEvaluator { ), PlanPropertyPath::Sequence(a, b) => { let eval = self.clone(); - let b = b.clone(); + let b = Rc::clone(b); Box::new(self.eval_open_in_unknown_graph(a).flat_map_ok( move |(start, middle, graph_name)| { eval.eval_from_in_graph(&b, &middle, &graph_name) @@ -3758,7 +3724,7 @@ impl PathEvaluator { )), PlanPropertyPath::ZeroOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); Box::new(transitive_closure( self.get_subject_or_object_identity_pairs_in_dataset(), move |(start, middle, graph_name)| { @@ -3769,7 +3735,7 @@ impl PathEvaluator { } PlanPropertyPath::OneOrMore(p) => { let eval = self.clone(); - let p = p.clone(); + let p = Rc::clone(p); Box::new(transitive_closure( self.eval_open_in_unknown_graph(&p), move |(start, middle, graph_name)| { @@ -3783,7 +3749,7 @@ impl PathEvaluator { .chain(self.eval_open_in_unknown_graph(p)), )), PlanPropertyPath::NegatedPropertySet(ps) => { - let ps = ps.clone(); + let ps = Rc::clone(ps); Box::new( self.dataset .encoded_quads_for_pattern(None, None, None, None) @@ -4050,9 +4016,9 @@ struct BadForLoopLeftJoinIterator { from_tuple: EncodedTuple, right_evaluator: Rc EncodedTuplesIterator>, left_iter: EncodedTuplesIterator, - current_left: Option, + current_left: EncodedTuple, current_right: EncodedTuplesIterator, - problem_vars: Rc>, + problem_vars: Rc<[usize]>, } impl Iterator for BadForLoopLeftJoinIterator { @@ -4062,9 +4028,7 @@ impl Iterator for BadForLoopLeftJoinIterator { for right_tuple in &mut self.current_right { match right_tuple { Ok(right_tuple) => { - if let Some(combined) = - right_tuple.combine_with(self.current_left.as_ref().unwrap()) - { + if let Some(combined) = right_tuple.combine_with(&self.current_left) { return Some(Ok(combined)); } } @@ -4086,7 +4050,7 @@ impl Iterator for BadForLoopLeftJoinIterator { match right_tuple { Ok(right_tuple) => { if let Some(combined) = right_tuple.combine_with(&left_tuple) { - self.current_left = Some(left_tuple); + self.current_left = left_tuple; return Some(Ok(combined)); } } @@ -4270,8 +4234,8 @@ impl Iterator for DescribeIterator { .eval .dataset .decode_quad(&quad) - .map(|q| q.into()) - .map_err(|e| e.into()), + .map(Into::into) + .map_err(Into::into), Err(error) => Err(error), }); } @@ -4522,9 +4486,9 @@ impl Accumulator for SumAccumulator { self.sum = match operands { NumericBinaryOperands::Float(v1, v2) => Some((v1 + v2).into()), NumericBinaryOperands::Double(v1, v2) => Some((v1 + v2).into()), - NumericBinaryOperands::Integer(v1, v2) => v1.checked_add(v2).map(|v| v.into()), - NumericBinaryOperands::Decimal(v1, v2) => v1.checked_add(v2).map(|v| v.into()), - NumericBinaryOperands::Duration(v1, v2) => v1.checked_add(v2).map(|v| v.into()), + NumericBinaryOperands::Integer(v1, v2) => v1.checked_add(v2).map(Into::into), + NumericBinaryOperands::Decimal(v1, v2) => v1.checked_add(v2).map(Into::into), + NumericBinaryOperands::Duration(v1, v2) => v1.checked_add(v2).map(Into::into), _ => None, }; } else { @@ -4562,9 +4526,9 @@ impl Accumulator for AvgAccumulator { NumericBinaryOperands::Float(v1, v2) => Some((v1 / v2).into()), NumericBinaryOperands::Double(v1, v2) => Some((v1 / v2).into()), NumericBinaryOperands::Integer(v1, v2) => { - Decimal::from(v1).checked_div(v2).map(|v| v.into()) + Decimal::from(v1).checked_div(v2).map(Into::into) } - NumericBinaryOperands::Decimal(v1, v2) => v1.checked_div(v2).map(|v| v.into()), + NumericBinaryOperands::Decimal(v1, v2) => v1.checked_div(v2).map(Into::into), _ => None, } } @@ -4649,14 +4613,14 @@ struct GroupConcatAccumulator { dataset: Rc, concat: Option, language: Option>, - separator: Rc, + separator: Rc, } impl GroupConcatAccumulator { - fn new(dataset: Rc, separator: Rc) -> Self { + fn new(dataset: Rc, separator: Rc) -> Self { Self { dataset, - concat: Some("".to_owned()), + concat: Some(String::new()), language: None, separator, } diff --git a/lib/src/sparql/model.rs b/lib/src/sparql/model.rs index 70cad955..d7c69ca7 100644 --- a/lib/src/sparql/model.rs +++ b/lib/src/sparql/model.rs @@ -160,6 +160,7 @@ impl From> for QueryResults { /// } /// # Result::<_,Box>::Ok(()) /// ``` +#[allow(clippy::rc_buffer)] pub struct QuerySolutionIter { variables: Rc>, iter: Box>>, @@ -171,8 +172,10 @@ impl QuerySolutionIter { iter: impl Iterator>, EvaluationError>> + 'static, ) -> Self { Self { - variables: variables.clone(), - iter: Box::new(iter.map(move |t| t.map(|values| (variables.clone(), values).into()))), + variables: Rc::clone(&variables), + iter: Box::new( + iter.map(move |t| t.map(|values| (Rc::clone(&variables), values).into())), + ), } } diff --git a/lib/src/sparql/plan.rs b/lib/src/sparql/plan.rs index bdd4b9e2..c9af7f22 100644 --- a/lib/src/sparql/plan.rs +++ b/lib/src/sparql/plan.rs @@ -22,7 +22,7 @@ pub enum PlanNode { }, Service { service_name: PatternValue, - variables: Rc>, + variables: Rc<[Variable]>, child: Rc, graph_pattern: Rc, silent: bool, @@ -71,7 +71,7 @@ pub enum PlanNode { ForLoopLeftJoin { left: Rc, right: Rc, - possible_problem_vars: Rc>, //Variables that should not be part of the entry of the left join + possible_problem_vars: Rc<[usize]>, //Variables that should not be part of the entry of the left join }, Extend { child: Rc, @@ -99,13 +99,13 @@ pub enum PlanNode { }, Project { child: Rc, - mapping: Rc>, // pairs of (variable key in child, variable key in output) + mapping: Rc<[(PlanVariable, PlanVariable)]>, // pairs of (variable key in child, variable key in output) }, Aggregate { // By definition the group by key are the range 0..key_mapping.len() child: Rc, - key_variables: Rc>, - aggregates: Rc>, + key_variables: Rc<[PlanVariable]>, + aggregates: Rc<[(PlanAggregation, PlanVariable)]>, }, } @@ -236,7 +236,10 @@ impl PlanNode { match self { Self::StaticBindings { encoded_tuples, .. } => { let mut variables = BTreeMap::default(); // value true iff always bound - let max_tuple_length = encoded_tuples.iter().map(|t| t.capacity()).fold(0, max); + let max_tuple_length = encoded_tuples + .iter() + .map(EncodedTuple::capacity) + .fold(0, max); for tuple in encoded_tuples { for key in 0..max_tuple_length { match variables.entry(key) { @@ -649,6 +652,7 @@ impl PlanExpression { } impl fmt::Display for PlanExpression { + #[allow(clippy::many_single_char_names)] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Variable(v) => { @@ -838,7 +842,7 @@ pub enum PlanAggregationFunction { Max, Avg, Sample, - GroupConcat { separator: Rc }, + GroupConcat { separator: Rc }, } #[derive(Debug, Clone)] @@ -850,7 +854,7 @@ pub enum PlanPropertyPath { ZeroOrMore(Rc), OneOrMore(Rc), ZeroOrOne(Rc), - NegatedPropertySet(Rc>>), + NegatedPropertySet(Rc<[PlanTerm]>), } impl fmt::Display for PlanPropertyPath { @@ -1046,7 +1050,7 @@ impl PlanNodeWithStats { "Aggregate({})", key_variables .iter() - .map(|c| c.to_string()) + .map(ToString::to_string) .chain(aggregates.iter().map(|(agg, v)| format!("{agg} -> {v}"))) .collect::>() .join(", ") @@ -1107,7 +1111,7 @@ impl PlanNodeWithStats { format!( "Sort({})", by.iter() - .map(|c| c.to_string()) + .map(ToString::to_string) .collect::>() .join(", ") ) @@ -1117,7 +1121,7 @@ impl PlanNodeWithStats { "StaticBindings({})", variables .iter() - .map(|v| v.to_string()) + .map(ToString::to_string) .collect::>() .join(", ") ) diff --git a/lib/src/sparql/plan_builder.rs b/lib/src/sparql/plan_builder.rs index 0b152db1..9e6472ec 100644 --- a/lib/src/sparql/plan_builder.rs +++ b/lib/src/sparql/plan_builder.rs @@ -122,7 +122,7 @@ impl<'a> PlanBuilder<'a> { PlanNode::ForLoopLeftJoin { left: Rc::new(left), right: Rc::new(right), - possible_problem_vars: Rc::new(possible_problem_vars.into_iter().collect()), + possible_problem_vars: possible_problem_vars.into_iter().collect(), } } else { PlanNode::HashLeftJoin { @@ -191,7 +191,7 @@ impl<'a> PlanBuilder<'a> { let service_name = self.pattern_value_from_named_node_or_variable(name, variables); PlanNode::Service { service_name, - variables: Rc::new(variables.clone()), + variables: Rc::from(variables.as_slice()), child: Rc::new(child), graph_pattern: Rc::new(inner.as_ref().clone()), silent: *silent, @@ -203,22 +203,19 @@ impl<'a> PlanBuilder<'a> { aggregates, } => PlanNode::Aggregate { child: Rc::new(self.build_for_graph_pattern(inner, variables, graph_name)?), - key_variables: Rc::new( - by.iter() - .map(|k| build_plan_variable(variables, k)) - .collect(), - ), - aggregates: Rc::new( - aggregates - .iter() - .map(|(v, a)| { - Ok(( - self.build_for_aggregate(a, variables, graph_name)?, - build_plan_variable(variables, v), - )) - }) - .collect::, EvaluationError>>()?, - ), + key_variables: by + .iter() + .map(|k| build_plan_variable(variables, k)) + .collect(), + aggregates: aggregates + .iter() + .map(|(v, a)| { + Ok(( + self.build_for_aggregate(a, variables, graph_name)?, + build_plan_variable(variables, v), + )) + }) + .collect::>()?, }, GraphPattern::Values { variables: table_variables, @@ -283,21 +280,19 @@ impl<'a> PlanBuilder<'a> { &mut inner_variables, &inner_graph_name, )?), - mapping: Rc::new( - projection - .iter() - .enumerate() - .map(|(new_variable, variable)| { - ( - PlanVariable { - encoded: new_variable, - plain: variable.clone(), - }, - build_plan_variable(variables, variable), - ) - }) - .collect(), - ), + mapping: projection + .iter() + .enumerate() + .map(|(new_variable, variable)| { + ( + PlanVariable { + encoded: new_variable, + plain: variable.clone(), + }, + build_plan_variable(variables, variable), + ) + }) + .collect(), } } GraphPattern::Distinct { inner } => PlanNode::HashDeduplicate { @@ -378,16 +373,14 @@ impl<'a> PlanBuilder<'a> { PropertyPathExpression::ZeroOrOne(p) => { PlanPropertyPath::ZeroOrOne(Rc::new(self.build_for_path(p))) } - PropertyPathExpression::NegatedPropertySet(p) => { - PlanPropertyPath::NegatedPropertySet(Rc::new( - p.iter() - .map(|p| PlanTerm { - encoded: self.build_term(p), - plain: p.clone(), - }) - .collect(), - )) - } + PropertyPathExpression::NegatedPropertySet(p) => PlanPropertyPath::NegatedPropertySet( + p.iter() + .map(|p| PlanTerm { + encoded: self.build_term(p), + plain: p.clone(), + }) + .collect(), + ), } } @@ -1084,7 +1077,7 @@ impl<'a> PlanBuilder<'a> { separator, } => Ok(PlanAggregation { function: PlanAggregationFunction::GroupConcat { - separator: Rc::new(separator.clone().unwrap_or_else(|| " ".to_owned())), + separator: Rc::from(separator.as_deref().unwrap_or(" ")), }, parameter: Some(self.build_for_expression(expr, variables, graph_name)?), distinct: *distinct, @@ -1219,13 +1212,11 @@ impl<'a> PlanBuilder<'a> { } fn convert_plan_variable(from_variable: &PlanVariable, to: &mut Vec) -> PlanVariable { - let encoded = if let Some(to_id) = to.iter().enumerate().find_map(|(to_id, var)| { - if *var == from_variable.plain { - Some(to_id) - } else { - None - } - }) { + let encoded = if let Some(to_id) = to + .iter() + .enumerate() + .find_map(|(to_id, var)| (*var == from_variable.plain).then(|| to_id)) + { to_id } else { to.push(Variable::new_unchecked(format!("{:x}", random::()))); @@ -1423,25 +1414,25 @@ impl<'a> PlanBuilder<'a> { if filter_variables.iter().all(|v| left.is_variable_bound(*v)) { if filter_variables.iter().all(|v| right.is_variable_bound(*v)) { PlanNode::HashJoin { - left: Rc::new(self.push_filter(left.clone(), filter.clone())), - right: Rc::new(self.push_filter(right.clone(), filter)), + left: Rc::new(self.push_filter(Rc::clone(left), filter.clone())), + right: Rc::new(self.push_filter(Rc::clone(right), filter)), } } else { PlanNode::HashJoin { - left: Rc::new(self.push_filter(left.clone(), filter)), - right: right.clone(), + left: Rc::new(self.push_filter(Rc::clone(left), filter)), + right: Rc::clone(right), } } } else if filter_variables.iter().all(|v| right.is_variable_bound(*v)) { PlanNode::HashJoin { - left: left.clone(), - right: Rc::new(self.push_filter(right.clone(), filter)), + left: Rc::clone(left), + right: Rc::new(self.push_filter(Rc::clone(right), filter)), } } else { PlanNode::Filter { child: Rc::new(PlanNode::HashJoin { - left: left.clone(), - right: right.clone(), + left: Rc::clone(left), + right: Rc::clone(right), }), expression: filter, } @@ -1450,20 +1441,20 @@ impl<'a> PlanBuilder<'a> { PlanNode::ForLoopJoin { left, right } => { if filter_variables.iter().all(|v| left.is_variable_bound(*v)) { PlanNode::ForLoopJoin { - left: Rc::new(self.push_filter(left.clone(), filter)), - right: right.clone(), + left: Rc::new(self.push_filter(Rc::clone(left), filter)), + right: Rc::clone(right), } } else if filter_variables.iter().all(|v| right.is_variable_bound(*v)) { PlanNode::ForLoopJoin { //TODO: should we do that always? - left: left.clone(), - right: Rc::new(self.push_filter(right.clone(), filter)), + left: Rc::clone(left), + right: Rc::new(self.push_filter(Rc::clone(right), filter)), } } else { PlanNode::Filter { child: Rc::new(PlanNode::HashJoin { - left: left.clone(), - right: right.clone(), + left: Rc::clone(left), + right: Rc::clone(right), }), expression: filter, } @@ -1477,14 +1468,14 @@ impl<'a> PlanBuilder<'a> { //TODO: handle the case where the filter generates an expression variable if filter_variables.iter().all(|v| child.is_variable_bound(*v)) { PlanNode::Extend { - child: Rc::new(self.push_filter(child.clone(), filter)), + child: Rc::new(self.push_filter(Rc::clone(child), filter)), expression: expression.clone(), variable: variable.clone(), } } else { PlanNode::Filter { child: Rc::new(PlanNode::Extend { - child: child.clone(), + child: Rc::clone(child), expression: expression.clone(), variable: variable.clone(), }), @@ -1495,12 +1486,12 @@ impl<'a> PlanBuilder<'a> { PlanNode::Filter { child, expression } => { if filter_variables.iter().all(|v| child.is_variable_bound(*v)) { PlanNode::Filter { - child: Rc::new(self.push_filter(child.clone(), filter)), + child: Rc::new(self.push_filter(Rc::clone(child), filter)), expression: expression.clone(), } } else { PlanNode::Filter { - child: child.clone(), + child: Rc::clone(child), expression: Box::new(PlanExpression::And(expression.clone(), filter)), } } @@ -1508,7 +1499,7 @@ impl<'a> PlanBuilder<'a> { PlanNode::Union { children } => PlanNode::Union { children: children .iter() - .map(|c| Rc::new(self.push_filter(c.clone(), filter.clone()))) + .map(|c| Rc::new(self.push_filter(Rc::clone(c), filter.clone()))) .collect(), }, _ => PlanNode::Filter { @@ -1541,12 +1532,11 @@ impl<'a> PlanBuilder<'a> { } fn build_plan_variable(variables: &mut Vec, variable: &Variable) -> PlanVariable { - let encoded = match slice_key(variables, variable) { - Some(key) => key, - None => { - variables.push(variable.clone()); - variables.len() - 1 - } + let encoded = if let Some(key) = slice_key(variables, variable) { + key + } else { + variables.push(variable.clone()); + variables.len() - 1 }; PlanVariable { plain: variable.clone(), @@ -1555,12 +1545,11 @@ fn build_plan_variable(variables: &mut Vec, variable: &Variable) -> Pl } fn bnode_key(blank_nodes: &mut Vec, blank_node: &BlankNode) -> usize { - match slice_key(blank_nodes, blank_node) { - Some(key) => key, - None => { - blank_nodes.push(blank_node.clone()); - blank_nodes.len() - 1 - } + if let Some(key) = slice_key(blank_nodes, blank_node) { + key + } else { + blank_nodes.push(blank_node.clone()); + blank_nodes.len() - 1 } } @@ -1673,21 +1662,13 @@ fn compile_static_pattern_if_exists( options: Option<&Expression>, ) -> Option { let static_pattern = if let Expression::Literal(pattern) = pattern { - if pattern.datatype() == xsd::STRING { - Some(pattern.value()) - } else { - None - } + (pattern.datatype() == xsd::STRING).then(|| pattern.value()) } else { None }; let static_options = if let Some(options) = options { if let Expression::Literal(options) = options { - if options.datatype() == xsd::STRING { - Some(Some(options.value())) - } else { - None - } + (options.datatype() == xsd::STRING).then(|| Some(options.value())) } else { None } diff --git a/lib/src/sparql/update.rs b/lib/src/sparql/update.rs index dff7d02c..2da5d08c 100644 --- a/lib/src/sparql/update.rs +++ b/lib/src/sparql/update.rs @@ -71,7 +71,14 @@ impl<'a, 'b: 'a> SimpleUpdateEvaluator<'a, 'b> { insert, pattern, .. - } => self.eval_delete_insert(delete, insert, using_dataset.as_ref().unwrap(), pattern), + } => self.eval_delete_insert( + delete, + insert, + using_dataset + .as_ref() + .ok_or_else(|| EvaluationError::msg("No dataset"))?, + pattern, + ), GraphUpdateOperation::Load { silent, source, @@ -119,14 +126,14 @@ impl<'a, 'b: 'a> SimpleUpdateEvaluator<'a, 'b> { ) -> Result<(), EvaluationError> { let dataset = Rc::new(DatasetView::new(self.transaction.reader(), using)); let (plan, variables) = PlanBuilder::build( - dataset.as_ref(), + &dataset, algebra, false, &self.options.query_options.custom_functions, !self.options.query_options.without_optimizations, )?; let evaluator = SimpleEvaluator::new( - dataset.clone(), + Rc::clone(&dataset), self.base_iri.clone(), self.options.query_options.service_handler(), Rc::new(self.options.query_options.custom_functions.clone()), @@ -374,7 +381,7 @@ impl<'a, 'b: 'a> SimpleUpdateEvaluator<'a, 'b> { TermPattern::Literal(term) => Some(term.clone().into()), TermPattern::Triple(triple) => { Self::convert_triple_pattern(triple, variables, values, dataset, bnodes)? - .map(|t| t.into()) + .map(Into::into) } TermPattern::Variable(v) => Self::lookup_variable(v, variables, values) .map(|node| dataset.decode_term(&node)) @@ -507,7 +514,7 @@ impl<'a, 'b: 'a> SimpleUpdateEvaluator<'a, 'b> { GroundTermPattern::Literal(term) => Some(term.clone().into()), GroundTermPattern::Triple(triple) => { Self::convert_ground_triple_pattern(triple, variables, values, dataset)? - .map(|t| t.into()) + .map(Into::into) } GroundTermPattern::Variable(v) => Self::lookup_variable(v, variables, values) .map(|node| dataset.decode_term(&node)) diff --git a/lib/src/storage/backend/fallback.rs b/lib/src/storage/backend/fallback.rs index 4c4a1ded..6000863b 100644 --- a/lib/src/storage/backend/fallback.rs +++ b/lib/src/storage/backend/fallback.rs @@ -29,20 +29,18 @@ impl Db { Ok(Self(Arc::new(RwLock::new(trees)))) } + #[allow(clippy::unwrap_in_result)] pub fn column_family(&self, name: &'static str) -> Option { let name = ColumnFamily(name); - if self.0.read().unwrap().contains_key(&name) { - Some(name) - } else { - None - } + (self.0.read().unwrap().contains_key(&name)).then(|| name) } #[must_use] pub fn snapshot(&self) -> Reader { - Reader(InnerReader::Simple(self.0.clone())) + Reader(InnerReader::Simple(Arc::clone(&self.0))) } + #[allow(clippy::unwrap_in_result)] pub fn transaction<'a, 'b: 'a, T, E: Error + 'static + From>( &'b self, f: impl Fn(Transaction<'a>) -> Result, @@ -64,6 +62,7 @@ enum InnerReader { } impl Reader { + #[allow(clippy::unwrap_in_result)] pub fn get( &self, column_family: &ColumnFamily, @@ -90,6 +89,7 @@ impl Reader { } } + #[allow(clippy::unwrap_in_result)] pub fn contains_key( &self, column_family: &ColumnFamily, @@ -120,6 +120,7 @@ impl Reader { self.scan_prefix(column_family, &[]) } + #[allow(clippy::unwrap_in_result)] pub fn scan_prefix( &self, column_family: &ColumnFamily, @@ -176,19 +177,20 @@ impl Reader { Ok(Iter { iter, current }) } + #[allow(clippy::unwrap_in_result)] pub fn len(&self, column_family: &ColumnFamily) -> Result { match &self.0 { InnerReader::Simple(reader) => Ok(reader .read() .unwrap() .get(column_family) - .map_or(0, |tree| tree.len())), + .map_or(0, BTreeMap::len)), InnerReader::Transaction(reader) => { if let Some(reader) = reader.upgrade() { Ok((*reader) .borrow() .get(column_family) - .map_or(0, |tree| tree.len())) + .map_or(0, BTreeMap::len)) } else { Err(StorageError::Other( "The transaction is already ended".into(), @@ -198,19 +200,20 @@ impl Reader { } } + #[allow(clippy::unwrap_in_result)] pub fn is_empty(&self, column_family: &ColumnFamily) -> Result { match &self.0 { InnerReader::Simple(reader) => Ok(reader .read() .unwrap() .get(column_family) - .map_or(true, |tree| tree.is_empty())), + .map_or(true, BTreeMap::is_empty)), InnerReader::Transaction(reader) => { if let Some(reader) = reader.upgrade() { Ok((*reader) .borrow() .get(column_family) - .map_or(true, |tree| tree.is_empty())) + .map_or(true, BTreeMap::is_empty)) } else { Err(StorageError::Other( "The transaction is already ended".into(), @@ -246,7 +249,7 @@ impl Transaction<'_> { .map_or(false, |cf| cf.contains_key(key))) } - #[allow(clippy::unnecessary_wraps)] + #[allow(clippy::unnecessary_wraps, clippy::unwrap_in_result)] pub fn insert( &mut self, column_family: &ColumnFamily, @@ -269,7 +272,7 @@ impl Transaction<'_> { self.insert(column_family, key, &[]) } - #[allow(clippy::unnecessary_wraps)] + #[allow(clippy::unnecessary_wraps, clippy::unwrap_in_result)] pub fn remove(&mut self, column_family: &ColumnFamily, key: &[u8]) -> Result<(), StorageError> { self.0 .borrow_mut() diff --git a/lib/src/storage/backend/rocksdb.rs b/lib/src/storage/backend/rocksdb.rs index 6da4be07..7a1e22eb 100644 --- a/lib/src/storage/backend/rocksdb.rs +++ b/lib/src/storage/backend/rocksdb.rs @@ -4,7 +4,7 @@ use crate::storage::error::{CorruptionError, StorageError}; use lazy_static::lazy_static; -use libc::{self, c_char, c_void, free}; +use libc::{self, c_void, free}; use oxrocksdb_sys::*; use rand::random; use std::borrow::Borrow; @@ -241,7 +241,7 @@ impl Db { .map(|cf| cf.as_ptr()) .collect::>() .as_ptr(), - cf_options.as_ptr() as *const *const rocksdb_options_t, + cf_options.as_ptr().cast(), cf_handles.as_mut_ptr(), )) .map_err(|e| { @@ -359,7 +359,7 @@ impl Db { .map(|cf| cf.as_ptr()) .collect::>() .as_ptr(), - cf_options.as_ptr() as *const *const rocksdb_options_t, + cf_options.as_ptr().cast(), cf_handles.as_mut_ptr(), )) .map_err(|e| { @@ -393,11 +393,7 @@ impl Db { cf_handles, cf_options, is_secondary: true, - path_to_remove: if in_memory { - Some(secondary_path) - } else { - None - }, + path_to_remove: in_memory.then(|| secondary_path), })), }) } @@ -424,7 +420,7 @@ impl Db { .map(|cf| cf.as_ptr()) .collect::>() .as_ptr(), - cf_options.as_ptr() as *const *const rocksdb_options_t, + cf_options.as_ptr().cast(), cf_handles.as_mut_ptr(), 0, // false )) @@ -580,7 +576,7 @@ impl Db { } let options = rocksdb_readoptions_create_copy(db.read_options); Reader { - inner: InnerReader::PlainDb(db.clone()), + inner: InnerReader::PlainDb(Arc::clone(db)), options, } } @@ -594,7 +590,7 @@ impl Db { rocksdb_readoptions_set_snapshot(options, snapshot); Reader { inner: InnerReader::TransactionalSnapshot(Rc::new(TransactionalSnapshot { - db: db.clone(), + db: Arc::clone(db), snapshot, })), options, @@ -698,7 +694,7 @@ impl Db { db.db, db.read_options, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len(), )) } @@ -707,7 +703,7 @@ impl Db { db.db, db.read_options, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len() )) } @@ -740,9 +736,9 @@ impl Db { db.db, db.write_options, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len(), - value.as_ptr() as *const c_char, + value.as_ptr().cast(), value.len(), )) }?; @@ -940,7 +936,7 @@ impl Reader { inner.db.db, self.options, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len() )) } @@ -950,7 +946,7 @@ impl Reader { *inner, self.options, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len() )) } else { @@ -964,7 +960,7 @@ impl Reader { inner.db, self.options, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len() )) } @@ -1005,11 +1001,7 @@ impl Reader { break; } } - if found { - Some(bound) - } else { - None - } + found.then(|| bound) }; unsafe { @@ -1021,7 +1013,7 @@ impl Reader { if let Some(upper_bound) = &upper_bound { rocksdb_readoptions_set_iterate_upper_bound( options, - upper_bound.as_ptr() as *const c_char, + upper_bound.as_ptr().cast(), upper_bound.len(), ); } @@ -1046,7 +1038,7 @@ impl Reader { if prefix.is_empty() { rocksdb_iter_seek_to_first(iter); } else { - rocksdb_iter_seek(iter, prefix.as_ptr() as *const c_char, prefix.len()); + rocksdb_iter_seek(iter, prefix.as_ptr().cast(), prefix.len()); } let is_currently_valid = rocksdb_iter_valid(iter) != 0; Ok(Iter { @@ -1101,7 +1093,7 @@ impl Transaction<'_> { *self.transaction, self.read_options, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len() ))?; Ok(if slice.is_null() { @@ -1130,9 +1122,9 @@ impl Transaction<'_> { ffi_result!(rocksdb_transaction_put_cf_with_status( *self.transaction, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len(), - value.as_ptr() as *const c_char, + value.as_ptr().cast(), value.len(), ))?; } @@ -1152,7 +1144,7 @@ impl Transaction<'_> { ffi_result!(rocksdb_transaction_delete_cf_with_status( *self.transaction, column_family.0, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len(), ))?; } @@ -1177,7 +1169,7 @@ impl Deref for PinnableSlice { unsafe { let mut len = 0; let val = rocksdb_pinnableslice_value(self.0, &mut len); - slice::from_raw_parts(val as *const u8, len) + slice::from_raw_parts(val.cast(), len) } } } @@ -1208,7 +1200,7 @@ pub struct Buffer { impl Drop for Buffer { fn drop(&mut self) { unsafe { - free(self.base as *mut c_void); + free(self.base.cast()); } } } @@ -1285,7 +1277,7 @@ impl Iter { unsafe { let mut len = 0; let val = rocksdb_iter_key(self.iter, &mut len); - Some(slice::from_raw_parts(val as *const u8, len)) + Some(slice::from_raw_parts(val.cast(), len)) } } else { None @@ -1311,9 +1303,9 @@ impl SstFileWriter { unsafe { ffi_result!(rocksdb_sstfilewriter_put_with_status( self.writer, - key.as_ptr() as *const c_char, + key.as_ptr().cast(), key.len(), - value.as_ptr() as *const c_char, + value.as_ptr().cast(), value.len(), ))?; } diff --git a/lib/src/storage/mod.rs b/lib/src/storage/mod.rs index 1dbebcfa..8a92e77f 100644 --- a/lib/src/storage/mod.rs +++ b/lib/src/storage/mod.rs @@ -1,3 +1,4 @@ +#![allow(clippy::same_name_method)] #[cfg(not(target_family = "wasm"))] use crate::model::Quad; use crate::model::{GraphNameRef, NamedOrBlankNodeRef, QuadRef, TermRef}; @@ -181,7 +182,7 @@ impl Storage { ] } - #[allow(clippy::unnecessary_wraps)] + #[allow(clippy::unnecessary_wraps, clippy::unwrap_in_result)] fn setup(db: Db) -> Result { let this = Self { #[cfg(not(target_family = "wasm"))] @@ -1305,7 +1306,7 @@ impl StorageBulkLoader { let mut buffer_to_load = Vec::with_capacity(batch_size); swap(buffer, &mut buffer_to_load); let storage = self.storage.clone(); - let done_counter_clone = done_counter.clone(); + let done_counter_clone = Arc::clone(done_counter); threads.push_back(spawn(move || { FileBulkLoader::new(storage, batch_size).load(buffer_to_load, &done_counter_clone) })); diff --git a/lib/src/store.rs b/lib/src/store.rs index 95234498..3d854a4a 100644 --- a/lib/src/store.rs +++ b/lib/src/store.rs @@ -565,7 +565,7 @@ impl Store { &self, quads: impl IntoIterator>, ) -> Result<(), StorageError> { - let quads = quads.into_iter().map(|q| q.into()).collect::>(); + let quads = quads.into_iter().map(Into::into).collect::>(); self.transaction(move |mut t| t.extend(&quads)) } @@ -1569,7 +1569,7 @@ impl BulkLoader { quads: impl IntoIterator, EI>>, ) -> Result<(), EO> { self.storage - .load(quads.into_iter().map(|q| q.map(|q| q.into()))) + .load(quads.into_iter().map(|q| q.map(Into::into))) } } diff --git a/lib/tests/store.rs b/lib/tests/store.rs index 66d2fae0..5f8a6809 100644 --- a/lib/tests/store.rs +++ b/lib/tests/store.rs @@ -175,7 +175,7 @@ fn test_load_dataset() -> Result<(), Box> { #[test] #[cfg(not(target_family = "wasm"))] fn test_bulk_load_dataset() -> Result<(), Box> { - let store = Store::new().unwrap(); + let store = Store::new()?; store .bulk_loader() .load_dataset(Cursor::new(GRAPH_DATA), DatasetFormat::TriG, None)?; diff --git a/python/src/io.rs b/python/src/io.rs index b4fbf3c5..c3032990 100644 --- a/python/src/io.rs +++ b/python/src/io.rs @@ -9,6 +9,7 @@ use pyo3::exceptions::{PyIOError, PySyntaxError, PyValueError}; use pyo3::prelude::*; use pyo3::types::PyBytes; use pyo3::wrap_pyfunction; +use std::error::Error; use std::fs::File; use std::io::{self, BufRead, BufReader, BufWriter, Cursor, Read, Write}; @@ -289,11 +290,7 @@ impl Read for PyIo { .map_err(to_io_err)?; let bytes = read .extract::<&[u8]>(py) - .or_else(|e| { - read.extract::<&str>(py) - .map(|s| s.as_bytes()) - .map_err(|_| e) - }) + .or_else(|e| read.extract::<&str>(py).map(str::as_bytes).map_err(|_| e)) .map_err(to_io_err)?; buf.write_all(bytes)?; Ok(bytes.len()) @@ -325,7 +322,10 @@ fn to_io_err(error: impl Into) -> io::Error { } pub fn map_io_err(error: io::Error) -> PyErr { - if error.get_ref().map_or(false, |s| s.is::()) { + if error + .get_ref() + .map_or(false, <(dyn Error + Send + Sync + 'static)>::is::) + { *error.into_inner().unwrap().downcast().unwrap() } else { PyIOError::new_err(error.to_string()) diff --git a/python/src/sparql.rs b/python/src/sparql.rs index 0fe9ceff..1cd0e1b2 100644 --- a/python/src/sparql.rs +++ b/python/src/sparql.rs @@ -225,7 +225,7 @@ impl PyQueryTriples { Ok(allow_threads_unsafe(|| self.inner.next()) .transpose() .map_err(map_evaluation_error)? - .map(|t| t.into())) + .map(Into::into)) } } diff --git a/python/src/store.rs b/python/src/store.rs index e0790aca..7dbb9a66 100644 --- a/python/src/store.rs +++ b/python/src/store.rs @@ -228,10 +228,10 @@ impl PyStore { extract_quads_pattern(subject, predicate, object, graph_name)?; Ok(QuadIter { inner: self.inner.quads_for_pattern( - subject.as_ref().map(|p| p.into()), - predicate.as_ref().map(|p| p.into()), - object.as_ref().map(|p| p.into()), - graph_name.as_ref().map(|p| p.into()), + subject.as_ref().map(Into::into), + predicate.as_ref().map(Into::into), + object.as_ref().map(Into::into), + graph_name.as_ref().map(Into::into), ), }) } diff --git a/server/src/main.rs b/server/src/main.rs index e095d495..1264f132 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -591,7 +591,7 @@ pub fn main() -> anyhow::Result<()> { let mut file = BufWriter::new(File::create(&explain_file)?); match explain_file .extension() - .and_then(|e| e.to_str()) { + .and_then(OsStr::to_str) { Some("json") => { explanation.write_in_json(file)?; }, @@ -734,7 +734,7 @@ fn format_from_path( path: &Path, from_extension: impl FnOnce(&str) -> anyhow::Result, ) -> anyhow::Result { - if let Some(ext) = path.extension().and_then(|ext| ext.to_str()) { + if let Some(ext) = path.extension().and_then(OsStr::to_str) { from_extension(ext).map_err(|e| { e.context(format!( "Not able to guess the file format from file name extension '{ext}'" @@ -1636,7 +1636,7 @@ impl io::Result>) + 'static> ReadForWrite Result { let buffer = Rc::new(RefCell::new(Vec::new())); let state = initial_state_builder(ReadForWriteWriter { - buffer: buffer.clone(), + buffer: Rc::clone(&buffer), }) .map_err(internal_server_error)?; Ok(Response::builder(Status::OK) diff --git a/testsuite/src/manifest.rs b/testsuite/src/manifest.rs index fcf79b36..1b93f244 100644 --- a/testsuite/src/manifest.rs +++ b/testsuite/src/manifest.rs @@ -347,7 +347,7 @@ impl<'a> Iterator for RdfListIterator<'a> { let result = self .graph .object_for_subject_predicate(current, rdf::FIRST) - .map(|v| v.into_owned()); + .map(TermRef::into_owned); self.current_node = match self.graph.object_for_subject_predicate(current, rdf::REST) { Some(TermRef::NamedNode(n)) if n == rdf::NIL => None, diff --git a/testsuite/src/sparql_evaluator.rs b/testsuite/src/sparql_evaluator.rs index 44153c68..4790d175 100644 --- a/testsuite/src/sparql_evaluator.rs +++ b/testsuite/src/sparql_evaluator.rs @@ -287,21 +287,11 @@ fn evaluate_update_evaluation_test(test: &Test) -> Result<()> { } fn load_sparql_query_result(url: &str) -> Result { - if url.ends_with(".srx") { - StaticQueryResults::from_query_results( - QueryResults::read(read_file(url)?, QueryResultsFormat::Xml)?, - false, - ) - } else if url.ends_with(".srj") { - StaticQueryResults::from_query_results( - QueryResults::read(read_file(url)?, QueryResultsFormat::Json)?, - false, - ) - } else if url.ends_with(".tsv") { - StaticQueryResults::from_query_results( - QueryResults::read(read_file(url)?, QueryResultsFormat::Tsv)?, - false, - ) + if let Some(format) = url + .rsplit_once('.') + .and_then(|(_, extension)| QueryResultsFormat::from_extension(extension)) + { + StaticQueryResults::from_query_results(QueryResults::read(read_file(url)?, format)?, false) } else { StaticQueryResults::from_graph(&load_graph(url, guess_graph_format(url)?)?) } @@ -505,7 +495,7 @@ impl StaticQueryResults { fn from_graph(graph: &Graph) -> Result { // Hack to normalize literals - let store = Store::new().unwrap(); + let store = Store::new()?; for t in graph.iter() { store .insert(t.in_graph(GraphNameRef::DefaultGraph)) @@ -617,12 +607,12 @@ fn results_diff(expected: StaticQueryResults, actual: StaticQueryResults) -> Str format_diff( &expected_variables .iter() - .map(|v| v.to_string()) + .map(ToString::to_string) .collect::>() .join("\n"), &actual_variables .iter() - .map(|v| v.to_string()) + .map(ToString::to_string) .collect::>() .join("\n"), "variables",