diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2cb3324..d79e72a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,22 +16,37 @@ jobs: strategy: matrix: include: + - rust: stable + features: - rust: stable features: std - rust: stable features: serde + - rust: stable + features: std,serde - rust: beta features: + - rust: beta + features: std + - rust: beta + features: serde + - rust: beta + features: std,serde - rust: nightly features: - + - rust: nightly + features: std + - rust: nightly + features: serde + - rust: nightly + features: std,serde steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} - name: Build - run: cargo build --verbose --features "${{ matrix.features }}" + run: cargo build --verbose --no-default-features --features "${{ matrix.features }}" nostd_build: runs-on: ubuntu-latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d58168c..8efb64c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,14 +16,30 @@ jobs: strategy: matrix: include: + - rust: stable + features: - rust: stable features: std - rust: stable features: serde + - rust: stable + features: std,serde - rust: beta features: + - rust: beta + features: std + - rust: beta + features: serde + - rust: beta + features: std,serde - rust: nightly features: + - rust: nightly + features: std + - rust: nightly + features: serde + - rust: nightly + features: std,serde steps: - uses: actions/checkout@v4 @@ -31,7 +47,7 @@ jobs: with: toolchain: ${{ matrix.rust }} - name: Run tests - run: cargo test --verbose --features "${{ matrix.features }}" + run: cargo test --verbose --no-default-features --features "${{ matrix.features }}" - name: Run tests in release mode - run: cargo test --release --verbose --features "${{ matrix.features }}" + run: cargo test --release --verbose --no-default-features --features "${{ matrix.features }}" diff --git a/Cargo.toml b/Cargo.toml index 5d5a5f2..ac4a98d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.65.0" [dependencies] equivalent = "1.0.1" indexmap = {version = "2.2", features = [], default-features = false} -serde = { version = "1", optional = true } +serde = { version = "1", optional = true, features = ["alloc"], default-features = false } [dev-dependencies] serde_test = "1" @@ -23,10 +23,11 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" uuid = {version= "1", features = ["v4", "serde"] } hashbrown = "0.14" +twox-hash = { version = "1.5", default-features = false } [features] default = ["std"] -std = ["indexmap/std"] +std = ["indexmap/std", "serde/std"] benchmarks = [] [workspace] diff --git a/src/double_priority_queue/mod.rs b/src/double_priority_queue/mod.rs index d15246d..2402f2c 100644 --- a/src/double_priority_queue/mod.rs +++ b/src/double_priority_queue/mod.rs @@ -473,6 +473,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::DoublePriorityQueue; /// let mut pq = DoublePriorityQueue::new(); /// @@ -486,6 +487,7 @@ where /// /// assert_eq!(pq.peek_min(), Some((&"Bananas", &15))); /// assert_eq!(pq.into_vec(), vec!["Bananas"]); + /// # } /// ``` pub fn extract_if(&mut self, predicate: F) -> ExtractIf where @@ -512,6 +514,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::DoublePriorityQueue; /// let mut pq = DoublePriorityQueue::new(); /// @@ -524,6 +527,7 @@ where /// }), None); /// /// assert_eq!(pq.pop_min(), Some(("Bananas", 10))); + /// # } /// ``` pub fn pop_min_if(&mut self, f: F) -> Option<(I, P)> where @@ -554,6 +558,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::DoublePriorityQueue; /// let mut pq = DoublePriorityQueue::new(); /// pq.push("Apples", 5); @@ -563,6 +568,7 @@ where /// false /// }), None); /// assert_eq!(pq.pop_max(), Some(("Apples", 5))); + /// # } /// ``` pub fn pop_max_if(&mut self, f: F) -> Option<(I, P)> where @@ -583,6 +589,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::DoublePriorityQueue; /// let mut pq = DoublePriorityQueue::new(); /// assert_eq!(pq.push("Apples", 5), None); @@ -591,6 +598,7 @@ where /// assert_eq!(pq.get_priority("Apples"), Some(&6)); /// assert_eq!(pq.push("Apples", 4), Some(6)); /// assert_eq!(pq.get_priority("Apples"), Some(&4)); + /// # } /// ``` /// /// Computes in **O(log(N))** time. @@ -641,6 +649,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::DoublePriorityQueue; /// let mut pq = DoublePriorityQueue::new(); /// assert_eq!(pq.push_increase("Apples", 5), None); @@ -651,6 +660,7 @@ where /// // priority is returned. /// assert_eq!(pq.push_increase("Apples", 4), Some(4)); /// assert_eq!(pq.get_priority("Apples"), Some(&6)); + /// # } /// ``` /// /// Computes in **O(log(N))** time. @@ -679,6 +689,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::DoublePriorityQueue; /// let mut pq = DoublePriorityQueue::new(); /// assert_eq!(pq.push_decrease("Apples", 5), None); @@ -689,6 +700,7 @@ where /// // priority is returned. /// assert_eq!(pq.push_decrease("Apples", 6), Some(6)); /// assert_eq!(pq.get_priority("Apples"), Some(&4)); + /// # } /// ``` /// /// Computes in **O(log(N))** time. @@ -708,6 +720,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::DoublePriorityQueue; /// let mut pq = DoublePriorityQueue::new(); /// assert_eq!(pq.change_priority("Apples", 5), None); @@ -716,6 +729,7 @@ where /// assert_eq!(pq.get_priority("Apples"), Some(&6)); /// assert_eq!(pq.change_priority("Apples", 4), Some(6)); /// assert_eq!(pq.get_priority("Apples"), Some(&4)); + /// # } /// ``` /// /// The item is found in **O(1)** thanks to the hash table. @@ -1218,8 +1232,8 @@ where #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] mod serde { - use std::cmp::{Eq, Ord}; - use std::hash::{BuildHasher, Hash}; + use core::cmp::{Eq, Ord}; + use core::hash::{BuildHasher, Hash}; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; diff --git a/src/lib.rs b/src/lib.rs index 34ae10d..0664dc8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,6 +54,7 @@ //! //! # Examples //! ```rust +//! # #[cfg(feature = "std")] { //! use priority_queue::PriorityQueue; //! //! let mut pq = PriorityQueue::new(); @@ -71,10 +72,12 @@ //! for (item, _) in pq.into_sorted_iter() { //! println!("{}", item); // Will print Bananas, Strawberries, Apples //! } +//! # } //! ``` //! //! ## Reverse ordering //! ```rust +//! # #[cfg(feature = "std")] { //! use priority_queue::PriorityQueue; //! use std::cmp::Reverse; //! @@ -90,6 +93,7 @@ //! for (item, _) in pq.into_sorted_iter() { //! println!("{}", item); // Will print Apples, Bananas, Strawberries //! } +//! # } //! ``` //! //! # Crate features diff --git a/src/priority_queue/mod.rs b/src/priority_queue/mod.rs index 8bc6f91..9aca048 100644 --- a/src/priority_queue/mod.rs +++ b/src/priority_queue/mod.rs @@ -62,6 +62,7 @@ use std::mem::replace; /// /// # Example /// ```rust +/// # #[cfg(feature = "std")] { /// use priority_queue::PriorityQueue; /// /// let mut pq = PriorityQueue::new(); @@ -79,6 +80,7 @@ use std::mem::replace; /// for (item, _) in pq.into_sorted_iter() { /// println!("{}", item); /// } +/// # } /// ``` #[derive(Clone, Debug)] #[cfg(feature = "std")] @@ -383,6 +385,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::PriorityQueue; /// let mut pq = PriorityQueue::new(); /// @@ -396,6 +399,7 @@ where /// /// assert_eq!(pq.peek(), Some((&"Bananas", &15))); /// assert_eq!(pq.into_vec(), vec!["Bananas"]); + /// # } /// ``` pub fn extract_if(&mut self, predicate: F) -> ExtractIf where @@ -422,6 +426,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::PriorityQueue; /// let mut pq = PriorityQueue::new(); /// @@ -434,6 +439,7 @@ where /// }), None); /// /// assert_eq!(pq.pop(), Some(("Apples", 5))); + /// # } /// ``` pub fn pop_if(&mut self, predicate: F) -> Option<(I, P)> where @@ -458,6 +464,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::PriorityQueue; /// let mut pq = PriorityQueue::new(); /// assert_eq!(pq.push("Apples", 5), None); @@ -466,6 +473,7 @@ where /// assert_eq!(pq.get_priority("Apples"), Some(&6)); /// assert_eq!(pq.push("Apples", 4), Some(6)); /// assert_eq!(pq.get_priority("Apples"), Some(&4)); + /// # } /// ``` /// /// Computes in **O(log(N))** time. @@ -515,6 +523,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::PriorityQueue; /// let mut pq = PriorityQueue::new(); /// assert_eq!(pq.push_increase("Apples", 5), None); @@ -525,6 +534,7 @@ where /// // priority is returned. /// assert_eq!(pq.push_increase("Apples", 4), Some(4)); /// assert_eq!(pq.get_priority("Apples"), Some(&6)); + /// # } /// ``` /// /// Computes in **O(log(N))** time. @@ -553,6 +563,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::PriorityQueue; /// let mut pq = PriorityQueue::new(); /// assert_eq!(pq.push_decrease("Apples", 5), None); @@ -563,6 +574,7 @@ where /// // priority is returned. /// assert_eq!(pq.push_decrease("Apples", 6), Some(6)); /// assert_eq!(pq.get_priority("Apples"), Some(&4)); + /// # } /// ``` /// /// Computes in **O(log(N))** time. @@ -582,6 +594,7 @@ where /// /// # Example /// ``` + /// # #[cfg(feature = "std")] { /// # use priority_queue::PriorityQueue; /// let mut pq = PriorityQueue::new(); /// assert_eq!(pq.change_priority("Apples", 5), None); @@ -590,6 +603,7 @@ where /// assert_eq!(pq.get_priority("Apples"), Some(&6)); /// assert_eq!(pq.change_priority("Apples", 4), Some(6)); /// assert_eq!(pq.get_priority("Apples"), Some(&4)); + /// # } /// ``` /// /// The item is found in **O(1)** thanks to the hash table. @@ -970,8 +984,8 @@ where #[cfg(feature = "serde")] #[cfg_attr(docsrs, doc(cfg(feature = "serde")))] mod serde { - use std::cmp::{Eq, Ord}; - use std::hash::{BuildHasher, Hash}; + use core::cmp::{Eq, Ord}; + use core::hash::{BuildHasher, Hash}; use serde::de::{Deserialize, Deserializer}; use serde::ser::{Serialize, Serializer}; diff --git a/src/store.rs b/src/store.rs index 816c44c..cee2ebc 100644 --- a/src/store.rs +++ b/src/store.rs @@ -692,10 +692,11 @@ where mod serde { use crate::store::{Index, Position, Store}; - use std::cmp::{Eq, Ord}; + use core::cmp::{Eq, Ord}; + use core::hash::{BuildHasher, Hash}; + use core::marker::PhantomData; + #[cfg(feature = "std")] use std::collections::hash_map::RandomState; - use std::hash::{BuildHasher, Hash}; - use std::marker::PhantomData; use serde::ser::{Serialize, SerializeSeq, Serializer}; @@ -733,6 +734,7 @@ mod serde { } } + #[cfg(feature = "std")] struct StoreVisitor where I: Hash + Eq, @@ -740,6 +742,16 @@ mod serde { { marker: PhantomData>, } + + #[cfg(not(feature = "std"))] + struct StoreVisitor + where + I: Hash + Eq, + P: Ord, + { + marker: PhantomData>, + } + impl<'de, I, P, H> Visitor<'de> for StoreVisitor where I: Hash + Eq + Deserialize<'de>, @@ -748,7 +760,7 @@ mod serde { { type Value = Store; - fn expecting(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result { write!(formatter, "A priority queue") } diff --git a/tests/double_priority_queue.rs b/tests/double_priority_queue.rs index 396c982..e60a39f 100644 --- a/tests/double_priority_queue.rs +++ b/tests/double_priority_queue.rs @@ -25,7 +25,7 @@ * obtain one at http://mozilla.org/MPL/2.0/. * */ - +#[cfg(feature = "std")] #[cfg(test)] mod doublepq_tests { pub use priority_queue::DoublePriorityQueue; @@ -1260,16 +1260,30 @@ mod doublepq_tests { mod serde_tests_basics { use priority_queue::DoublePriorityQueue; use serde_test::{assert_tokens, Token}; + + #[cfg(not(feature = "std"))] + use core::hash::BuildHasherDefault; + #[cfg(not(feature = "std"))] + use twox_hash::XxHash64; + #[test] fn serde_empty() { + #[cfg(feature = "std")] let pq: DoublePriorityQueue = DoublePriorityQueue::new(); + #[cfg(not(feature = "std"))] + let pq: DoublePriorityQueue> = + DoublePriorityQueue::default(); assert_tokens(&pq, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); } #[test] fn serde() { + #[cfg(feature = "std")] let mut pq = DoublePriorityQueue::new(); + #[cfg(not(feature = "std"))] + let mut pq: DoublePriorityQueue<&str, i32, BuildHasherDefault> = + DoublePriorityQueue::default(); pq.push("a", 1); pq.push("b", 2); @@ -1317,6 +1331,11 @@ mod serde_tests_custom_structs { use std::time::Duration; use uuid::Uuid; + #[cfg(not(feature = "std"))] + use core::hash::BuildHasherDefault; + #[cfg(not(feature = "std"))] + use twox_hash::XxHash64; + use serde::{Deserialize, Serialize}; // Abusing Duration as a mutable std::time::Instant @@ -1410,9 +1429,12 @@ mod serde_tests_custom_structs { fn test1() { println!("test1()"); + #[cfg(feature = "std")] type PqType = DoublePriorityQueue; + #[cfg(not(feature = "std"))] + type PqType = DoublePriorityQueue>; - let mut pq: PqType = DoublePriorityQueue::new(); + let mut pq: PqType = DoublePriorityQueue::default(); pq.push(0, 0); pq.push(1, 1); @@ -1429,9 +1451,12 @@ mod serde_tests_custom_structs { fn test2() { println!("\n\ntest2()"); + #[cfg(feature = "std")] type PqType = DoublePriorityQueue; + #[cfg(not(feature = "std"))] + type PqType = DoublePriorityQueue>; - let mut pq: PqType = DoublePriorityQueue::new(); + let mut pq: PqType = DoublePriorityQueue::default(); pq.push(0, Default::default()); // Uuids will be different pq.push(1, Default::default()); @@ -1488,9 +1513,13 @@ mod serde_tests_custom_structs { assert_eq!(ec2, deserialized); { + #[cfg(feature = "std")] type PqType = DoublePriorityQueue; + #[cfg(not(feature = "std"))] + type PqType = + DoublePriorityQueue>; - let mut pq: PqType = DoublePriorityQueue::new(); + let mut pq: PqType = DoublePriorityQueue::default(); pq.push(ce1, ec1); pq.push(ce2, ec2); diff --git a/tests/priority_queue.rs b/tests/priority_queue.rs index 1a7a5b9..cbad1c4 100644 --- a/tests/priority_queue.rs +++ b/tests/priority_queue.rs @@ -26,6 +26,7 @@ * */ +#[cfg(feature = "std")] #[cfg(test)] mod pqueue_tests { pub use priority_queue::PriorityQueue; @@ -1075,16 +1076,29 @@ mod pqueue_tests { mod serde_tests_basics { use priority_queue::PriorityQueue; use serde_test::{assert_tokens, Token}; + + #[cfg(not(feature = "std"))] + use core::hash::BuildHasherDefault; + #[cfg(not(feature = "std"))] + use twox_hash::XxHash64; + #[test] fn serde_empty() { + #[cfg(feature = "std")] let pq: PriorityQueue = PriorityQueue::new(); + #[cfg(not(feature = "std"))] + let pq: PriorityQueue> = PriorityQueue::default(); assert_tokens(&pq, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); } #[test] fn serde() { + #[cfg(feature = "std")] let mut pq = PriorityQueue::new(); + #[cfg(not(feature = "std"))] + let mut pq: PriorityQueue<&str, i32, BuildHasherDefault> = + PriorityQueue::default(); pq.push("a", 1); pq.push("b", 2); @@ -1126,12 +1140,17 @@ mod serde_tests_basics { //thanks to ckaran #[cfg(all(feature = "serde", test))] mod serde_tests_custom_structs { + use core::cmp::{Ord, Ordering, PartialOrd}; + use core::default::Default; + use core::time::Duration; use priority_queue::PriorityQueue; - use std::cmp::{Ord, Ordering, PartialOrd}; - use std::default::Default; - use std::time::Duration; use uuid::Uuid; + #[cfg(not(feature = "std"))] + use core::hash::BuildHasherDefault; + #[cfg(not(feature = "std"))] + use twox_hash::XxHash64; + use serde::{Deserialize, Serialize}; // Abusing Duration as a mutable std::time::Instant @@ -1225,9 +1244,12 @@ mod serde_tests_custom_structs { fn test1() { println!("test1()"); + #[cfg(feature = "std")] type PqType = PriorityQueue; + #[cfg(not(feature = "std"))] + type PqType = PriorityQueue>; - let mut pq: PqType = PriorityQueue::new(); + let mut pq: PqType = PriorityQueue::default(); pq.push(0, 0); pq.push(1, 1); @@ -1244,9 +1266,12 @@ mod serde_tests_custom_structs { fn test2() { println!("\n\ntest2()"); + #[cfg(feature = "std")] type PqType = PriorityQueue; + #[cfg(not(feature = "std"))] + type PqType = PriorityQueue>; - let mut pq: PqType = PriorityQueue::new(); + let mut pq: PqType = PriorityQueue::default(); pq.push(0, Default::default()); // Uuids will be different pq.push(1, Default::default()); @@ -1303,9 +1328,13 @@ mod serde_tests_custom_structs { assert_eq!(ec2, deserialized); { + #[cfg(feature = "std")] type PqType = PriorityQueue; + #[cfg(not(feature = "std"))] + type PqType = + PriorityQueue>; - let mut pq: PqType = PriorityQueue::new(); + let mut pq: PqType = PriorityQueue::default(); pq.push(ce1, ec1); pq.push(ce2, ec2);