1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
// Mit License from https://github.com/rust-lang/rust // // Permission is hereby granted, free of charge, to any // person obtaining a copy of this software and associated // documentation files (the "Software"), to deal in the // Software without restriction, including without // limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software // is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice // shall be included in all copies or substantial portions // of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. // ignore-tidy-undocumented-unsafe //! __Safe failable sort, min, max, binary_search functions for PartialOrd. No need to wrap `f32`, `f64` to sort any more.__ //! //! This crate provides helper traits for type with only [`PartialOrd`] but not [`Ord`]( like [`f32`], [`f64`]), to use methods where [`Ord`](`core::cmp::Ord`) is needed, like sort, min, max and binary_search. //! These methods are almost same as the methods for Ord, exept that it returns [`InvalidOrderError`] when the [`partial_cmp`](`std::cmp::PartialOrd::partial_cmp`) //! returns [`None`](`core::option::Option::None`). //! These traits have `try_` methods like [`try_sort`](`TrySort::try_sort`) for [`slice::sort`]. //! //! This is safer than using something like `sort_by` with ignoreing None case of [`partial_cmp`](`std::cmp::PartialOrd::partial_cmp`) because it handle error instead of panic. //! //! Sort is using the same logic as std. //! //! This supports `no_std` with no `std` feature flag. //! //! ``` //! use try_partialord::*; //! use rand::distributions::Standard; //! use rand::prelude::*; //! //! let mut vec: Vec<f32> = Standard.sample_iter(thread_rng()).take(100).collect(); //! //no NAN in vec so sort should succed //! let sort_result = vec.try_sort(); //! assert!(sort_result.is_ok()); //! assert!(vec.try_is_sorted().unwrap_or(false)); //! //! vec.push(f32::NAN); //! //NAN in vec so sort should fail //! let sort_result = vec.try_sort(); //! assert!(sort_result.is_err()); //! assert!(vec.try_is_sorted().is_err()); //! ``` #![cfg_attr(not(feature = "std"), no_std)] mod binary_search; mod min_max; mod sort; pub use binary_search::TryBinarySearch; use core::fmt::{Display, Error, Formatter}; pub use min_max::TryMinMax; pub use sort::TrySort; /// Error when [`partial_cmp`](`std::cmp::PartialOrd::partial_cmp`) returns [`None`] during the operation. #[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default, Debug)] pub struct InvalidOrderError; impl Display for InvalidOrderError { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { fmt.write_str("Failed because partial_cmp returns None.") } } #[cfg(feature = "std")] impl std::error::Error for InvalidOrderError {} /// Alias for result pub type OrderResult<T> = Result<T, InvalidOrderError>; fn ord_as_cmp<T>(a: &T, b: &T) -> Option<bool> where T: PartialOrd<T>, { a.partial_cmp(b).map(|a| a == core::cmp::Ordering::Less) } /* pub trait HasOnlyInvalidOrderValue { fn is_invalid(&self) -> bool; fn as_ordered(self) -> Option<Ordered<Self>> where Self: Sized, { if self.is_invalid() { Some(Ordered(self)) } else { None } } } #[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)] pub struct Ordered<T>(T); impl<T: core::cmp::PartialEq> Eq for Ordered<T> {} impl<T: core::cmp::PartialOrd> Ord for Ordered<T> { fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.partial_cmp(other).unwrap() } } */