diff --git a/.clippy.toml b/.clippy.toml new file mode 100644 index 0000000..4781d68 --- /dev/null +++ b/.clippy.toml @@ -0,0 +1,10 @@ +# LINEBENDER LINT SET - .clippy.toml - v1 +# See https://linebender.org/wiki/canonical-lints/ + +# The default Clippy value is capped at 8 bytes, which was chosen to improve performance on 32-bit. +# Given that we are building for the future and even low-end mobile phones have 64-bit CPUs, +# it makes sense to optimize for 64-bit and accept the performance hits on 32-bit. +# 16 bytes is the number of bytes that fits into two 64-bit CPU registers. +trivial-copy-size-limit = 16 + +# END LINEBENDER LINT SET diff --git a/Cargo.toml b/Cargo.toml index 504956f..3ebf9e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,69 @@ edition = "2021" exclude = ["testing-tools/**"] rust-version = "1.65" +[lints] +rust.unsafe_code = "forbid" + +# LINEBENDER LINT SET - Cargo.toml - v3 +# See https://linebender.org/wiki/canonical-lints/ +rust.keyword_idents_2024 = "forbid" +rust.non_ascii_idents = "forbid" +rust.non_local_definitions = "forbid" +rust.unsafe_op_in_unsafe_fn = "forbid" + +rust.elided_lifetimes_in_paths = "warn" +rust.let_underscore_drop = "warn" +rust.missing_debug_implementations = "warn" +rust.missing_docs = "warn" +rust.single_use_lifetimes = "warn" +rust.trivial_numeric_casts = "warn" +rust.unexpected_cfgs = "warn" +rust.unit_bindings = "warn" +rust.unnameable_types = "warn" +rust.unreachable_pub = "warn" +rust.unused_import_braces = "warn" +rust.unused_lifetimes = "warn" +rust.unused_macro_rules = "warn" +rust.unused_qualifications = "warn" +rust.variant_size_differences = "warn" + +clippy.too_many_arguments = "allow" + +clippy.allow_attributes = "warn" +clippy.allow_attributes_without_reason = "warn" +clippy.cast_possible_truncation = "warn" +clippy.collection_is_never_read = "warn" +clippy.dbg_macro = "warn" +clippy.debug_assert_with_mut_call = "warn" +clippy.doc_markdown = "warn" +clippy.exhaustive_enums = "warn" +clippy.fn_to_numeric_cast_any = "warn" +clippy.infinite_loop = "warn" +clippy.large_include_file = "warn" +clippy.large_stack_arrays = "warn" +clippy.match_same_arms = "warn" +clippy.mismatching_type_param_order = "warn" +clippy.missing_assert_message = "warn" +clippy.missing_errors_doc = "warn" +clippy.missing_fields_in_debug = "warn" +clippy.missing_panics_doc = "warn" +clippy.partial_pub_fields = "warn" +clippy.return_self_not_must_use = "warn" +clippy.same_functions_in_if_condition = "warn" +clippy.semicolon_if_nothing_returned = "warn" +clippy.shadow_unrelated = "warn" +clippy.should_panic_without_expect = "warn" +clippy.todo = "warn" +clippy.unseparated_literal_suffix = "warn" +clippy.use_self = "warn" +clippy.wildcard_imports = "warn" + +clippy.cargo_common_metadata = "warn" +clippy.negative_feature_names = "warn" +clippy.redundant_feature_names = "warn" +clippy.wildcard_dependencies = "warn" +# END LINEBENDER LINT SET + [features] default = ["std"] std = ["log/std"] diff --git a/examples/parse.rs b/examples/parse.rs index 794be4a..0ad9752 100644 --- a/examples/parse.rs +++ b/examples/parse.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Parse + use std::io::{Read, Write}; fn main() { diff --git a/examples/select.rs b/examples/select.rs index a9ce360..329d8aa 100644 --- a/examples/select.rs +++ b/examples/select.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Select + struct XmlNode<'a, 'input: 'a>(roxmltree::Node<'a, 'input>); impl<'a, 'input: 'a> XmlNode<'a, 'input> { @@ -30,14 +32,18 @@ impl simplecss::Element for XmlNode<'_, '_> { self.0.tag_name().name() == local_name } - fn attribute_matches(&self, local_name: &str, operator: simplecss::AttributeOperator) -> bool { + fn attribute_matches( + &self, + local_name: &str, + operator: simplecss::AttributeOperator<'_>, + ) -> bool { match self.0.attribute(local_name) { Some(value) => operator.matches(value), None => false, } } - fn pseudo_class_matches(&self, class: simplecss::PseudoClass) -> bool { + fn pseudo_class_matches(&self, class: simplecss::PseudoClass<'_>) -> bool { match class { simplecss::PseudoClass::FirstChild => self.prev_sibling_element().is_none(), _ => false, // Since we are querying a static XML we can ignore other pseudo-classes. @@ -62,17 +68,20 @@ fn main() { .unwrap() .attribute("id") .unwrap(), - "rect1" + "rect1", + "selected wrong element" ); assert_eq!( root.select("[color=red]").unwrap().attribute("id").unwrap(), - "rect2" + "rect2", + "selected wrong element" ); assert_eq!( root.select("svg rect").unwrap().attribute("id").unwrap(), - "rect1" + "rect1", + "selected wrong element" ); assert_eq!( @@ -80,11 +89,13 @@ fn main() { .unwrap() .attribute("id") .unwrap(), - "rect1" + "rect1", + "selected wrong element" ); assert_eq!( root.select(".blue").unwrap().attribute("id").unwrap(), - "rect1" + "rect1", + "selected wrong element" ); } diff --git a/src/lib.rs b/src/lib.rs index 31d0a3e..04faa2e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,10 +29,32 @@ Since it's very simple we will start with limitations: - No unsafe. */ -#![doc(html_root_url = "https://docs.rs/simplecss/0.2.1")] +// LINEBENDER LINT SET - lib.rs - v2 +// See https://linebender.org/wiki/canonical-lints/ +// These lints aren't included in Cargo.toml because they +// shouldn't apply to examples and tests +#![warn(unused_crate_dependencies)] +#![warn(clippy::print_stdout, clippy::print_stderr)] +// Targeting e.g. 32-bit means structs containing usize can give false positives for 64-bit. +#![cfg_attr(target_pointer_width = "64", warn(clippy::trivially_copy_pass_by_ref))] +// END LINEBENDER LINT SET +#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![cfg_attr(all(not(feature = "std"), not(test)), no_std)] -#![forbid(unsafe_code)] -#![warn(missing_docs)] +// The following lints are part of the Linebender standard set, +// but resolving them has been deferred for now. +// Feel free to send a PR that solves one or more of these. +#![allow( + missing_debug_implementations, + elided_lifetimes_in_paths, + single_use_lifetimes, + unreachable_pub, + clippy::use_self, + clippy::missing_assert_message, + clippy::missing_panics_doc, + clippy::exhaustive_enums, + clippy::unseparated_literal_suffix +)] +#![cfg_attr(test, allow(unused_crate_dependencies))] // Some dev dependencies are only used in tests extern crate alloc; @@ -258,7 +280,7 @@ impl fmt::Display for StyleSheet<'_> { } } -impl<'a> Default for StyleSheet<'a> { +impl Default for StyleSheet<'_> { fn default() -> Self { Self::new() } @@ -296,7 +318,7 @@ fn consume_rule_set<'a>(s: &mut Stream<'a>, rules: &mut Vec>) -> Result s.advance(1); } - let (selector, offset) = crate::selector::parse(s.slice_tail()); + let (selector, offset) = parse(s.slice_tail()); s.advance(offset); s.skip_spaces(); diff --git a/src/selector.rs b/src/selector.rs index d64b4d5..11f6a41 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -22,7 +22,7 @@ pub enum AttributeOperator<'a> { StartsWith(&'a str), } -impl<'a> AttributeOperator<'a> { +impl AttributeOperator<'_> { /// Checks that value is matching the operator. pub fn matches(&self, value: &str) -> bool { match *self { @@ -355,7 +355,7 @@ pub(crate) fn parse(text: &str) -> (Option, usize) { } } -impl<'a> fmt::Display for Selector<'a> { +impl fmt::Display for Selector<'_> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for component in &self.components { match component.combinator { diff --git a/tests/declaration_tokenizer.rs b/tests/declaration_tokenizer.rs index 1fda7b2..b64a7e4 100644 --- a/tests/declaration_tokenizer.rs +++ b/tests/declaration_tokenizer.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Declaration Tokenizer + use simplecss::*; macro_rules! tokenize { diff --git a/tests/select.rs b/tests/select.rs index 18366e3..02c8311 100644 --- a/tests/select.rs +++ b/tests/select.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Select + use simplecss::*; struct XmlNode<'a, 'input: 'a>(roxmltree::Node<'a, 'input>); @@ -19,7 +21,7 @@ impl<'a, 'input: 'a> XmlNode<'a, 'input> { } } -impl simplecss::Element for XmlNode<'_, '_> { +impl Element for XmlNode<'_, '_> { fn parent_element(&self) -> Option { self.0.parent_element().map(XmlNode) } @@ -36,14 +38,14 @@ impl simplecss::Element for XmlNode<'_, '_> { self.0.tag_name().name() == local_name } - fn attribute_matches(&self, local_name: &str, operator: AttributeOperator) -> bool { + fn attribute_matches(&self, local_name: &str, operator: AttributeOperator<'_>) -> bool { match self.0.attribute(local_name) { Some(value) => operator.matches(value), None => false, } } - fn pseudo_class_matches(&self, class: PseudoClass) -> bool { + fn pseudo_class_matches(&self, class: PseudoClass<'_>) -> bool { match class { PseudoClass::FirstChild => self.prev_sibling_element().is_none(), _ => false, diff --git a/tests/selector_tokenizer.rs b/tests/selector_tokenizer.rs index 0e85534..3c11d89 100644 --- a/tests/selector_tokenizer.rs +++ b/tests/selector_tokenizer.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Selector Tokenizer + use simplecss::*; macro_rules! tokenize { diff --git a/tests/specificity.rs b/tests/specificity.rs index 92736f9..b1e7084 100644 --- a/tests/specificity.rs +++ b/tests/specificity.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Specificity + use simplecss::*; #[test] diff --git a/tests/stylesheet.rs b/tests/stylesheet.rs index 808387f..846d65d 100644 --- a/tests/stylesheet.rs +++ b/tests/stylesheet.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Stylesheet + use simplecss::*; #[test] diff --git a/tests/warnings.rs b/tests/warnings.rs index 97ed609..f160ddb 100644 --- a/tests/warnings.rs +++ b/tests/warnings.rs @@ -1,6 +1,8 @@ // Copyright 2019 the SimpleCSS Authors // SPDX-License-Identifier: Apache-2.0 OR MIT +//! Warnings + fn run_process(input: &str) -> String { use std::io::Write; use std::process::Stdio;