Skip to content

Commit 5c6ec75

Browse files
authored
Merge pull request #23 from tcharding/12-29-improve
Do various improvements
2 parents 0c4b4e9 + 3760ece commit 5c6ec75

File tree

4 files changed

+220
-29
lines changed

4 files changed

+220
-29
lines changed

Cargo.toml

Lines changed: 131 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,140 @@ keywords = ["ord", "partialord", "wrapper"]
1111
readme = "README.md"
1212
edition = "2021"
1313
rust-version = "1.63.0"
14-
exclude = ["justfile", "rustfmt.toml", "clippy.toml"]
14+
exclude = ["tests", "contrib"]
15+
16+
[features]
1517

1618
[dependencies]
1719

18-
[features]
20+
[package.metadata.docs.rs]
21+
all-features = true
22+
rustdoc-args = ["--cfg", "docsrs"]
1923

2024
[[example]]
2125
name = "point"
26+
27+
[lints.clippy]
28+
# Exhaustive list of pedantic clippy lints
29+
assigning_clones = "warn"
30+
bool_to_int_with_if = "warn"
31+
borrow_as_ptr = "warn"
32+
case_sensitive_file_extension_comparisons = "warn"
33+
cast_lossless = "warn"
34+
cast_possible_truncation = "warn"
35+
cast_possible_wrap = "warn"
36+
cast_precision_loss = "warn"
37+
cast_ptr_alignment = "warn"
38+
cast_sign_loss = "warn"
39+
checked_conversions = "warn"
40+
cloned_instead_of_copied = "warn"
41+
copy_iterator = "warn"
42+
default_trait_access = "warn"
43+
doc_link_with_quotes = "warn"
44+
doc_markdown = "warn"
45+
empty_enum = "warn"
46+
enum_glob_use = "warn"
47+
expl_impl_clone_on_copy = "warn"
48+
explicit_deref_methods = "warn"
49+
explicit_into_iter_loop = "warn"
50+
explicit_iter_loop = "warn"
51+
filter_map_next = "warn"
52+
flat_map_option = "warn"
53+
float_cmp = "warn"
54+
fn_params_excessive_bools = "warn"
55+
from_iter_instead_of_collect = "warn"
56+
if_not_else = "warn"
57+
ignored_unit_patterns = "warn"
58+
implicit_clone = "warn"
59+
implicit_hasher = "warn"
60+
inconsistent_struct_constructor = "warn"
61+
index_refutable_slice = "warn"
62+
inefficient_to_string = "warn"
63+
inline_always = "warn"
64+
into_iter_without_iter = "warn"
65+
invalid_upcast_comparisons = "warn"
66+
items_after_statements = "warn"
67+
iter_filter_is_ok = "warn"
68+
iter_filter_is_some = "warn"
69+
iter_not_returning_iterator = "warn"
70+
iter_without_into_iter = "warn"
71+
large_digit_groups = "warn"
72+
large_futures = "warn"
73+
large_stack_arrays = "warn"
74+
large_types_passed_by_value = "warn"
75+
linkedlist = "warn"
76+
macro_use_imports = "warn"
77+
manual_assert = "warn"
78+
manual_instant_elapsed = "warn"
79+
manual_is_power_of_two = "warn"
80+
manual_is_variant_and = "warn"
81+
manual_let_else = "warn"
82+
manual_ok_or = "warn"
83+
manual_string_new = "warn"
84+
many_single_char_names = "warn"
85+
map_unwrap_or = "warn"
86+
match_bool = "warn"
87+
match_on_vec_items = "warn"
88+
match_same_arms = "warn"
89+
match_wild_err_arm = "warn"
90+
match_wildcard_for_single_variants = "warn"
91+
maybe_infinite_iter = "warn"
92+
mismatching_type_param_order = "warn"
93+
missing_errors_doc = "warn"
94+
missing_fields_in_debug = "warn"
95+
missing_panics_doc = "warn"
96+
must_use_candidate = "warn"
97+
mut_mut = "warn"
98+
naive_bytecount = "warn"
99+
needless_bitwise_bool = "warn"
100+
needless_continue = "warn"
101+
needless_for_each = "warn"
102+
needless_pass_by_value = "warn"
103+
needless_raw_string_hashes = "warn"
104+
no_effect_underscore_binding = "warn"
105+
no_mangle_with_rust_abi = "warn"
106+
option_as_ref_cloned = "warn"
107+
option_option = "warn"
108+
ptr_as_ptr = "warn"
109+
ptr_cast_constness = "warn"
110+
pub_underscore_fields = "warn"
111+
range_minus_one = "warn"
112+
range_plus_one = "warn"
113+
redundant_closure_for_method_calls = "warn"
114+
redundant_else = "warn"
115+
ref_as_ptr = "warn"
116+
ref_binding_to_reference = "warn"
117+
ref_option = "warn"
118+
ref_option_ref = "warn"
119+
return_self_not_must_use = "warn"
120+
same_functions_in_if_condition = "warn"
121+
semicolon_if_nothing_returned = "warn"
122+
should_panic_without_expect = "warn"
123+
similar_names = "warn"
124+
single_char_pattern = "warn"
125+
single_match_else = "warn"
126+
stable_sort_primitive = "warn"
127+
str_split_at_newline = "warn"
128+
string_add_assign = "warn"
129+
struct_excessive_bools = "warn"
130+
struct_field_names = "warn"
131+
too_many_lines = "warn"
132+
transmute_ptr_to_ptr = "warn"
133+
trivially_copy_pass_by_ref = "warn"
134+
unchecked_duration_subtraction = "warn"
135+
unicode_not_nfc = "warn"
136+
uninlined_format_args = "allow" # This is a subjective style choice.
137+
unnecessary_box_returns = "warn"
138+
unnecessary_join = "warn"
139+
unnecessary_literal_bound = "warn"
140+
unnecessary_wraps = "warn"
141+
unnested_or_patterns = "warn"
142+
unreadable_literal = "warn"
143+
unsafe_derive_deserialize = "warn"
144+
unused_async = "warn"
145+
unused_self = "warn"
146+
used_underscore_binding = "warn"
147+
used_underscore_items = "warn"
148+
verbose_bit_mask = "warn"
149+
wildcard_imports = "warn"
150+
zero_sized_map_values = "warn"

examples/point.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ fn main() {
1717

1818
println!();
1919
println!("Looking in map for key: {}", a);
20-
let found = map
21-
.get(Ordered::from_ref(&a))
22-
.expect("failed to look up key");
20+
let found = map.get(Ordered::from_ref(&a)).expect("failed to look up key");
2321
println!("Found it, with value: {}", found);
2422
}
2523

rustfmt.toml

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1-
max_width = 100
1+
ignore = []
22
hard_tabs = false
33
tab_spaces = 4
44
newline_style = "Auto"
55
indent_style = "Block"
6-
use_small_heuristics = "Default"
7-
fn_call_width = 80
8-
attr_fn_like_width = 70
9-
struct_lit_width = 80
10-
struct_variant_width = 35
11-
array_width = 60
12-
chain_width = 60
13-
single_line_if_else_max_width = 50
6+
7+
max_width = 100 # This is number of characters.
8+
# `use_small_heuristics` is ignored if the granular width config values are explicitly set.
9+
use_small_heuristics = "Max" # "Max" == All granular width settings same as `max_width`.
10+
# # Granular width configuration settings. These are percentages of `max_width`.
11+
# fn_call_width = 60
12+
# attr_fn_like_width = 70
13+
# struct_lit_width = 18
14+
# struct_variant_width = 35
15+
# array_width = 60
16+
# chain_width = 60
17+
# single_line_if_else_max_width = 50
18+
1419
wrap_comments = false
1520
format_code_in_doc_comments = false
16-
comment_width = 80
21+
comment_width = 100 # Default 80
1722
normalize_comments = false
1823
normalize_doc_attributes = false
1924
format_strings = false
@@ -22,7 +27,7 @@ format_macro_bodies = true
2227
hex_literal_case = "Preserve"
2328
empty_item_single_line = true
2429
struct_lit_single_line = true
25-
fn_single_line = true
30+
fn_single_line = true # Default false
2631
where_single_line = false
2732
imports_indent = "Block"
2833
imports_layout = "Mixed"
@@ -41,7 +46,7 @@ combine_control_expr = true
4146
overflow_delimited_expr = false
4247
struct_field_align_threshold = 0
4348
enum_discrim_align_threshold = 0
44-
match_arm_blocks = true
49+
match_arm_blocks = false # Default true
4550
match_arm_leading_pipes = "Never"
4651
force_multiline_blocks = false
4752
fn_params_layout = "Tall"
@@ -52,8 +57,8 @@ trailing_comma = "Vertical"
5257
match_block_trailing_comma = false
5358
blank_lines_upper_bound = 1
5459
blank_lines_lower_bound = 0
55-
edition = "2018"
56-
version = "One"
60+
edition = "2021"
61+
style_edition = "2021"
5762
inline_attribute_width = 0
5863
format_generated_files = true
5964
merge_derives = true
@@ -68,6 +73,5 @@ skip_children = false
6873
show_parse_errors = true
6974
error_on_line_overflow = false
7075
error_on_unformatted = false
71-
ignore = []
7276
emit_mode = "Files"
7377
make_backup = false

src/lib.rs

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,50 @@
33
//! Provides a wrapper for types that can technically implement `PartialOrd`/`Ord`
44
//! but for semantic reasons it is nonsensical.
55
//!
6-
//! For examples see the docs on [`Ordered`] or the code in `examples/point.rs`.
6+
//! # Examples
7+
//!
8+
//! ```
9+
//! # #![allow(unused)] // Because of `Adt`.
10+
//! use core::{cmp::Ordering, fmt};
11+
//! use ordered::{ArbitraryOrd, Ordered};
12+
//!
13+
//! /// A point in 2D space.
14+
//! ///
15+
//! /// We do not want users to be able to write `a < b` because it is not well defined.
16+
//! #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
17+
//! struct Point {
18+
//! x: u32,
19+
//! y: u32,
20+
//! }
21+
//!
22+
//! impl ArbitraryOrd for Point {
23+
//! fn arbitrary_cmp(&self, other: &Self) -> Ordering {
24+
//! // Just use whatever order tuple cmp gives us.
25+
//! (self.x, self.y).cmp(&(other.x, other.y))
26+
//! }
27+
//! }
28+
//!
29+
//! impl fmt::Display for Point {
30+
//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31+
//! write!(f, "({}, {})", self.x, self.y)
32+
//! }
33+
//! }
34+
//!
35+
//! /// `Ordered` allows users to derive `PartialOrd` on types that include a `Point`.
36+
//! #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
37+
//! struct Adt {
38+
//! name: String,
39+
//! point: Ordered<Point>,
40+
//! }
41+
//! ```
742
843
#![no_std]
944
// Experimental features we need.
1045
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
1146
// Coding conventions.
1247
#![warn(missing_docs)]
48+
#![warn(deprecated_in_future)]
49+
#![doc(test(attr(warn(unused))))]
1350

1451
use core::borrow::{Borrow, BorrowMut};
1552
use core::cmp::Ordering;
@@ -30,6 +67,7 @@ pub trait ArbitraryOrd: Eq + PartialEq {
3067
/// # Examples
3168
///
3269
/// ```
70+
/// # #![allow(unused)] // Because of `Adt`.
3371
/// use core::{cmp::Ordering, fmt};
3472
/// use ordered::{ArbitraryOrd, Ordered};
3573
///
@@ -58,9 +96,8 @@ pub trait ArbitraryOrd: Eq + PartialEq {
5896
/// let point = Point { x: 0, y: 1 };
5997
/// let ordered = Ordered(point);
6098
///
61-
/// println!("We can explicitly deref (*ordered): {}", *ordered);
62-
/// println!("Or use deref coercion (ordered): {}", ordered);
63-
/// println!("Or we can use borrow (&ordered): {}", &ordered);
99+
/// assert_eq!(*ordered, ordered.into_inner()); // Explicitly deref or use `into_inner()`.
100+
/// assert_eq!(&ordered.0, ordered.as_ref()); // Use `AsRef` or `as_ref()`.
64101
/// ```
65102
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
66103
#[repr(transparent)]
@@ -74,6 +111,12 @@ impl<T> Ordered<T> {
74111
/// The inner type is public so this function is never explicitly needed.
75112
pub const fn new(inner: T) -> Self { Self(inner) }
76113

114+
/// Creates an `Ordered<T>` from a reference.
115+
///
116+
/// This allows: `let found = map.get(Ordered::from_ref(&a));`
117+
#[allow(clippy::ptr_as_ptr)]
118+
pub fn from_ref(value: &T) -> &Self { unsafe { &*(value as *const _ as *const Self) } }
119+
77120
/// Returns a reference to the inner object.
78121
///
79122
/// We also implement [`core::borrow::Borrow`] so this function is never explicitly needed.
@@ -83,11 +126,6 @@ impl<T> Ordered<T> {
83126
///
84127
/// We also implement [`core::ops::Deref`] so this function is never explicitly needed.
85128
pub fn into_inner(self) -> T { self.0 }
86-
87-
/// Creates an `Ordered<T>` from a reference.
88-
///
89-
/// This allows: `let found = map.get(Ordered::from_ref(&a));`
90-
pub fn from_ref(value: &T) -> &Self { unsafe { &*(value as *const _ as *const Self) } }
91129
}
92130

93131
impl<T: ArbitraryOrd> ArbitraryOrd for &T {
@@ -179,4 +217,26 @@ mod tests {
179217

180218
assert!(Ordered(&a) < Ordered(&b));
181219
}
220+
221+
// Copied from https://rust-lang.github.io/api-guidelines/interoperability.html#c-send-sync
222+
#[test]
223+
fn send() {
224+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
225+
struct Point {
226+
x: u32,
227+
y: u32,
228+
}
229+
230+
impl ArbitraryOrd for Point {
231+
fn arbitrary_cmp(&self, other: &Self) -> Ordering {
232+
(self.x, self.y).cmp(&(other.x, other.y))
233+
}
234+
}
235+
236+
fn assert_send<T: Send>() {}
237+
fn assert_sync<T: Sync>() {}
238+
239+
assert_send::<Ordered<Point>>();
240+
assert_sync::<Ordered<Point>>();
241+
}
182242
}

0 commit comments

Comments
 (0)