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 118 119 120 121 122 123 124 125 126 127 128 129 130
use crate::{AnyBin, BinSegment, ExcessShrink, SegmentIterator}; /// Use this factory to create binaries. There's a built-in implementation in this crate; /// custom implementations (that implement this trait) are possible. pub trait BinFactory { /// The type this factory produces. type T: AnyBin; /// Empty binary. /// /// ```rust /// use abin::{NewBin, Bin, BinFactory}; /// let bin : Bin = NewBin::empty(); /// assert_eq!(0, bin.len()); /// ``` fn empty() -> Self::T; /// A binary from a `&'static [u8]`. /// /// ```rust /// use abin::{Bin, NewBin, BinFactory, AnyBin}; /// let bin : Bin = NewBin::from_static("Hello".as_bytes()); /// assert_eq!("Hello".as_bytes(), bin.as_slice()); /// ``` fn from_static(slice: &'static [u8]) -> Self::T; /// A binary from a `&[u8]`; prefer `from_static` if there's a static lifetime. /// /// ```rust /// use abin::{Bin, NewBin, BinFactory, AnyBin}; /// let bin : Bin = NewBin::copy_from_slice("Hello".as_bytes()); /// assert_eq!("Hello".as_bytes(), bin.as_slice()); /// ``` fn copy_from_slice(slice: &[u8]) -> Self::T; /// Create a binary from an iterator. To be efficient, the iterator should provide correct /// hints (see `Iterator::size_hint`). fn from_iter_with_config<T: GivenVecConfig, TIterator>(iter: TIterator) -> Self::T where TIterator: IntoIterator<Item = u8>; /// Create a binary from an iterator. To be efficient, the iterator should provide correct /// hints (see `Iterator::size_hint`). /// /// ```rust /// use abin::{Bin, NewBin, BinFactory, AnyBin}; /// let bin : Bin = NewBin::from_iter((0..6).map(|i| i as u8)); /// assert_eq!(&[0u8, 1u8, 2u8, 3u8, 4u8, 5u8], bin.as_slice()); /// ``` fn from_iter(iter: impl IntoIterator<Item = u8>) -> Self::T; /// Create a binary by joining multiple segments (see `BinSegment`). fn from_segments_with_config<'a, T: GivenVecConfig, TIterator>(iter: TIterator) -> Self::T where TIterator: SegmentIterator<BinSegment<'a, Self::T>>; /// Create a binary by joining multiple segments (see `BinSegment`). /// /// ```rust /// use abin::{BinSegment, SegmentsSlice, Bin, NewBin, BinFactory, AnyBin}; /// /// let segments = &mut [BinSegment::Static("Hello, ".as_bytes()), /// BinSegment::Static("World!".as_bytes())]; /// let iterator = SegmentsSlice::new(segments); /// let bin : Bin = NewBin::from_segments(iterator); /// assert_eq!("Hello, World!".as_bytes(), bin.as_slice()); /// ``` fn from_segments<'a>(iter: impl SegmentIterator<BinSegment<'a, Self::T>>) -> Self::T; /// Convert a `BinSegment` to a binary. fn from_segment_with_config<'a, T: GivenVecConfig, TSegment>(segment: TSegment) -> Self::T where TSegment: Into<BinSegment<'a, Self::T>>; /// Convert a `BinSegment` to a binary. /// /// ```rust /// use abin::{NewBin, BinFactory, BinSegment}; /// /// // both lines are equivalent (`from_segment` will just call `from_static`). /// let bin_1 = NewBin::from_static("Hello".as_bytes()); /// let bin_2 = NewBin::from_segment(BinSegment::Static("Hello".as_bytes())); /// /// assert_eq!(bin_1, bin_2); /// ``` fn from_segment<'a>(segment: impl Into<BinSegment<'a, Self::T>>) -> Self::T; /// Creates a binary from given vec. Important: Only use this method if you're given /// a `Vec<u8>` from outside (something you can't control). If you're in control, use /// any of the other methods provided by this factory (such as `from_iter`, `from_segments`). /// /// See `from_given_vec_with_config` with a default config chosen by the implementation. /// /// ```rust /// use abin::{NewBin, BinFactory, AnyBin}; /// let vec_from_string = "Hello".to_owned().into_bytes(); /// let bin = NewBin::from_given_vec(vec_from_string); /// assert_eq!("Hello".as_bytes(), bin.as_slice()); /// ``` fn from_given_vec(vec: Vec<u8>) -> Self::T; /// Creates a binary from given vec. Important: Only use this method if you're given /// a `Vec<u8>` from outside (something you can't control). If you're in control, use /// any of the other methods provided by this factory (such as `from_iter`, `from_segments`). fn from_given_vec_with_config<T: GivenVecConfig>(vec: Vec<u8>) -> Self::T; } /// Custom configuration used for `BinFactory::from_given_vec` / /// `BinFactory::from_given_vec_with_config`). pub trait GivenVecConfig { /// Shrink the given vector if there's too much excess? /// (excess = `Vec::capacity() - Vec::len()`). type TExcessShrink: ExcessShrink; /// Optimization hint. fn optimization() -> GivenVecOptimization; } /// Hint on what optimization to perform when constructing a binary from a `Vec<u8>`. Optimize /// for construction (see `BinFactory::from_given_vec`) or optimize for operations /// (such as `clone` or `slice`). #[derive(Debug, Eq, PartialEq)] pub enum GivenVecOptimization { /// Optimize for construction (when `AnyBin` is created from `Vec<u8>`). Operations (such as /// `clone` or `slice`) might be slower (require allocation / mem-copy). Construction, /// Optimize for operations (such as `clone`, `slice`). The creation (when `AnyBin` is created /// from `Vec<u8>`) might be slower (require allocation / mem-copy) instead. Operations, }