diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 90162f2..d2e3a33 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -55,7 +55,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Install nightly toolchain + - name: Install beta toolchain uses: actions-rs/toolchain@v1 with: profile: minimal @@ -84,7 +84,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Install stable toolchain + - name: Install nightly toolchain uses: actions-rs/toolchain@v1 with: toolchain: nightly @@ -95,3 +95,35 @@ jobs: with: command: test args: --all-features + + test-miri: + name: Test Miri + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Miri + run: | + rustup toolchain install nightly --component miri + rustup override set nightly + cargo miri setup + - name: Test with Miri + run: cargo miri test + + build-no-std: + name: Build no-std + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Install stable no-std toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: thumbv7em-none-eabihf + override: true + + - name: Run cargo build + uses: actions-rs/cargo@v1 + with: + command: build + args: --target thumbv7em-none-eabihf --all-features diff --git a/Cargo.toml b/Cargo.toml index 103311d..524e98d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ringbuffer" -version = "0.8.3" +version = "0.9.0" authors = [ "Victor Roest ", "Jonathan Dönszelmann ", @@ -10,7 +10,7 @@ description = "A fixed-size circular buffer" repository = "https://github.com/NULLx76/ringbuffer/" keywords = ["ring", "cyclic", "circular", "buffer", "no-std"] categories = ["data-structures"] -license = "LGPL-3.0" +license = "MIT" [dependencies] array-init = "2.0" diff --git a/LICENSE b/LICENSE index 65c5ca8..adac444 100644 --- a/LICENSE +++ b/LICENSE @@ -1,165 +1,21 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. +MIT License + +Copyright (c) 2022 Victor Roest and Jonathan Dönszelmann + +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. diff --git a/README.md b/README.md index c52c94d..765077e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,9 @@ Implementations for three kinds of ringbuffers, with a mostly similar API are pr All of these ringbuffers also implement the RingBuffer trait for their shared API surface. + +MSRV: Rust 1.55 + # Usage ```rust @@ -44,8 +47,8 @@ fn main() { | name | default | description | | --- | --- | --- | -| alloc | ✓ | Disable this feature to remove the dependency on alloc. Useful for kernels. | +| alloc | ✓ | Disable this feature to remove the dependency on alloc. The feature is compatible with `no_std`. | # License -Licensed under GNU Lesser General Public License v3.0 +Licensed under MIT License diff --git a/src/lib.rs b/src/lib.rs index 13b47de..041514d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -852,6 +852,8 @@ mod tests { } #[test] + #[cfg_attr(miri, ignore)] + // this test takes far too long with Miri enabled fn run_test_push_dequeue_push_full_get_rep() { fn test_push_dequeue_push_full_get_rep(mut rb: impl RingBufferExt) { for _ in 0..100_000 { @@ -973,24 +975,30 @@ mod tests { } macro_rules! test_dropped { - ($constructor: block) => { + ($constructor: block) => {{ + let dt = Box::into_raw(Box::new(RefCell::new(DropTest { flag: false }))); { - let dt = Box::leak(Box::new(RefCell::new(DropTest { flag: false }))); - { - let d = Dropee { parent: Some(dt.borrow_mut()) }; - let mut rb = { $constructor }; - rb.push(d); - rb.push(Dropee { parent: None }); - } - assert!(dt.borrow_mut().flag); - unsafe { - // SAFETY: we know Dropee, which needed the static lifetime, has been dropped (by the assert) - // we could probably skip this, but this makes sure we don't leak any memory - let ptr: *mut RefCell = std::mem::transmute::<&RefCell, _>(dt); - drop(Box::from_raw(ptr)); - } + let d = Dropee { + // Safety: + // We know the pointer is initialized as it was created just above. + // Also no other mutable borrow can exist at this time + parent: Some(unsafe { dt.as_ref() }.unwrap().borrow_mut()), + }; + let mut rb = { $constructor }; + rb.push(d); + rb.push(Dropee { parent: None }); } - }; + { + // Safety: + // We know the pointer exists and is no longer borrowed as the block above limited it + assert!(unsafe { dt.as_ref() }.unwrap().borrow().flag); + } + // Safety: + // No other references exist to box so we can safely drop it + unsafe { + drop(Box::from_raw(dt)); + } + }}; } #[test] diff --git a/src/ringbuffer_trait.rs b/src/ringbuffer_trait.rs index 710157e..01e37d3 100644 --- a/src/ringbuffer_trait.rs +++ b/src/ringbuffer_trait.rs @@ -98,7 +98,7 @@ pub trait RingBufferExt: where T: Default, { - self.fill_with(Default::default) + self.fill_with(Default::default); } /// Sets every element in the ringbuffer to `value` @@ -106,7 +106,7 @@ pub trait RingBufferExt: where T: Clone, { - self.fill_with(|| value.clone()) + self.fill_with(|| value.clone()); } /// Empties the buffer entirely. Sets the length to 0 but keeps the capacity allocated. @@ -320,7 +320,7 @@ mod iter { pub use iter::{RingBufferDrainingIterator, RingBufferIterator, RingBufferMutIterator}; -/// Implement various functions on implementors of RingBufferRead. +/// Implement various functions on implementors of [`RingBufferRead`]. /// This is to avoid duplicate code. macro_rules! impl_ringbuffer_read { () => { @@ -331,7 +331,7 @@ macro_rules! impl_ringbuffer_read { }; } -/// Implement various functions on implementors of RingBuffer. +/// Implement various functions on implementors of [`RingBuffer`]. /// This is to avoid duplicate code. macro_rules! impl_ringbuffer { ($readptr: ident, $writeptr: ident) => { @@ -342,7 +342,7 @@ macro_rules! impl_ringbuffer { }; } -/// Implement various functions on implementors of RingBufferExt. +/// Implement various functions on implementors of [`RingBufferExt`]. /// This is to avoid duplicate code. macro_rules! impl_ringbuffer_ext { ($get_unchecked: ident, $get_unchecked_mut: ident, $readptr: ident, $writeptr: ident, $mask: expr) => { diff --git a/src/with_alloc.rs b/src/with_alloc.rs index bc5df09..efd6cbc 100644 --- a/src/with_alloc.rs +++ b/src/with_alloc.rs @@ -3,7 +3,6 @@ use core::ops::{Index, IndexMut}; use crate::ringbuffer_trait::{RingBuffer, RingBufferExt, RingBufferRead, RingBufferWrite}; extern crate alloc; -extern crate std; // We need vecs so depend on alloc use alloc::vec::Vec; use core::iter::FromIterator; @@ -61,10 +60,7 @@ impl PartialEq for AllocRingBuffer { fn eq(&self, other: &Self) -> bool { self.capacity == other.capacity && self.len() == other.len() - && self - .iter() - .zip(other.iter()) - .fold(true, |p, (a, b)| p && a == b) + && self.iter().zip(other.iter()).all(|(a, b)| a == b) } } @@ -120,7 +116,7 @@ impl Extend for AllocRingBuffer { let iter = iter.into_iter(); for i in iter { - self.push(i) + self.push(i); } } } @@ -184,7 +180,7 @@ impl AllocRingBuffer { /// function raised to the power of two (effectively the input is the log2 of the actual capacity) #[inline] pub fn with_capacity_power_of_2(cap_power_of_two: usize) -> Self { - Self::with_capacity_unchecked(cap_power_of_two.pow(2)) + Self::with_capacity_unchecked(1 << cap_power_of_two) } #[inline] @@ -230,7 +226,7 @@ impl FromIterator for AllocRingBuffer { fn from_iter>(iter: T) -> Self { let mut res = Self::default(); for i in iter { - res.push(i) + res.push(i); } res diff --git a/src/with_const_generics.rs b/src/with_const_generics.rs index 5193cc2..0ddedaa 100644 --- a/src/with_const_generics.rs +++ b/src/with_const_generics.rs @@ -122,7 +122,7 @@ impl Extend for ConstGenericRingBuffer { let iter = iter.into_iter(); for i in iter { - self.push(i) + self.push(i); } } } @@ -201,7 +201,7 @@ impl FromIterator for ConstGenericRingBuffer fn from_iter>(iter: T) -> Self { let mut res = Self::default(); for i in iter { - res.push(i) + res.push(i); } res