mirror of
https://github.com/sile/hls_m3u8.git
synced 2024-11-22 15:21:01 +00:00
rewrite KeyFormatVersions
This commit is contained in:
parent
7025114e36
commit
b8fd4c15d5
1 changed files with 568 additions and 53 deletions
|
@ -1,8 +1,11 @@
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use std::iter::{Extend, FromIterator};
|
||||||
|
use std::ops::{Index, IndexMut};
|
||||||
|
use std::slice::SliceIndex;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use derive_more::{Deref, DerefMut};
|
|
||||||
|
|
||||||
use crate::types::ProtocolVersion;
|
use crate::types::ProtocolVersion;
|
||||||
use crate::utils::{quote, unquote};
|
use crate::utils::{quote, unquote};
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
@ -12,18 +15,49 @@ use crate::RequiredVersion;
|
||||||
/// this instance complies with, if more than one version of a particular
|
/// this instance complies with, if more than one version of a particular
|
||||||
/// [`KeyFormat`] is defined.
|
/// [`KeyFormat`] is defined.
|
||||||
///
|
///
|
||||||
|
/// ## Note on maximum size
|
||||||
|
///
|
||||||
|
/// To reduce the memory usage and to make this struct implement [`Copy`], a
|
||||||
|
/// fixed size array is used internally (`[u8; 9]`), which can store a maximum
|
||||||
|
/// number of 9 `u8` numbers.
|
||||||
|
///
|
||||||
|
/// If you encounter any m3u8 file, which fails to parse, because the buffer is
|
||||||
|
/// too small, feel free to [make an issue](https://github.com/sile/hls_m3u8/issues).
|
||||||
|
///
|
||||||
|
/// ## Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use hls_m3u8::types::KeyFormatVersions;
|
||||||
|
///
|
||||||
|
/// assert_eq!(
|
||||||
|
/// KeyFormatVersions::from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]).to_string(),
|
||||||
|
/// "\"255/255/255/255/255/255/255/255/255\"".to_string()
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
/// [`KeyFormat`]: crate::types::KeyFormat
|
/// [`KeyFormat`]: crate::types::KeyFormat
|
||||||
#[derive(Deref, DerefMut, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct KeyFormatVersions(Vec<usize>);
|
pub struct KeyFormatVersions {
|
||||||
|
// NOTE(Luro02): if the current array is not big enough one can easily increase
|
||||||
|
// the number of elements or change the type to something bigger,
|
||||||
|
// but it would be kinda wasteful to use a `Vec` here, which requires
|
||||||
|
// allocations and has a size of at least 24 bytes
|
||||||
|
// (::std::mem::size_of::<Vec<u8>>() = 24).
|
||||||
|
buffer: [u8; 9],
|
||||||
|
// Indicates the number of used items in the array.
|
||||||
|
len: u8,
|
||||||
|
}
|
||||||
|
|
||||||
impl KeyFormatVersions {
|
impl KeyFormatVersions {
|
||||||
/// Makes a new [`KeyFormatVersions`].
|
/// Constructs an empty [`KeyFormatVersions`].
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use hls_m3u8::types::KeyFormatVersions;
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
/// let key_format_versions = KeyFormatVersions::new();
|
/// let versions = KeyFormatVersions::new();
|
||||||
|
///
|
||||||
|
/// assert_eq!(versions, KeyFormatVersions::default());
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -31,40 +65,299 @@ impl KeyFormatVersions {
|
||||||
|
|
||||||
/// Add a value to the end of [`KeyFormatVersions`].
|
/// Add a value to the end of [`KeyFormatVersions`].
|
||||||
///
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// This function panics, if you try to push more elements, than
|
||||||
|
/// [`KeyFormatVersions::remaining`] returns.
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use hls_m3u8::types::KeyFormatVersions;
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
/// let mut key_format_versions = KeyFormatVersions::new();
|
/// let mut versions = KeyFormatVersions::new();
|
||||||
///
|
///
|
||||||
/// key_format_versions.push(1);
|
/// versions.push(1);
|
||||||
|
/// assert_eq!(versions, KeyFormatVersions::from([1]));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn push(&mut self, value: usize) {
|
///
|
||||||
if self.is_default() {
|
/// This will panic, because it exceeded the maximum number of elements:
|
||||||
self.0 = vec![value];
|
///
|
||||||
|
/// ```{.should_panic}
|
||||||
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
|
/// let mut versions = KeyFormatVersions::new();
|
||||||
|
///
|
||||||
|
/// for _ in 0..=versions.capacity() {
|
||||||
|
/// versions.push(1); // <- panics
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn push(&mut self, value: u8) {
|
||||||
|
if self.len as usize == self.buffer.len() {
|
||||||
|
panic!("reached maximum number of elements in KeyFormatVersions");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.buffer[self.len()] = value;
|
||||||
|
self.len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `KeyFormatVersions` has a limited capacity and this function returns how
|
||||||
|
/// many elements can be pushed, until it panics.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
|
/// let mut versions = KeyFormatVersions::new();
|
||||||
|
///
|
||||||
|
/// assert_eq!(versions.remaining(), versions.capacity());
|
||||||
|
///
|
||||||
|
/// versions.push(1);
|
||||||
|
/// versions.push(2);
|
||||||
|
/// versions.push(3);
|
||||||
|
/// assert_eq!(versions.remaining(), 6);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn remaining(&self) -> usize { self.capacity().saturating_sub(self.len()) }
|
||||||
|
|
||||||
|
/// Returns the number of elements.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
|
/// let mut versions = KeyFormatVersions::new();
|
||||||
|
///
|
||||||
|
/// assert_eq!(versions.len(), 0);
|
||||||
|
///
|
||||||
|
/// versions.push(2);
|
||||||
|
/// assert_eq!(versions.len(), 1);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub const fn len(&self) -> usize { self.len as usize }
|
||||||
|
|
||||||
|
/// Returns the total number of elements that can be stored.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
|
///
|
||||||
|
/// It should not be relied on that this function will always return 9. In
|
||||||
|
/// the future this number might increase.
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn capacity(&self) -> usize { self.buffer.len() }
|
||||||
|
|
||||||
|
/// Shortens the internal array to the provided length.
|
||||||
|
///
|
||||||
|
/// # Note
|
||||||
|
///
|
||||||
|
/// If `len` is greater than the current length, this has no effect.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
|
/// let mut versions = KeyFormatVersions::from([1, 2, 3, 4, 5, 6]);
|
||||||
|
/// versions.truncate(3);
|
||||||
|
///
|
||||||
|
/// assert_eq!(versions, KeyFormatVersions::from([1, 2, 3]));
|
||||||
|
/// ```
|
||||||
|
pub fn truncate(&mut self, len: usize) {
|
||||||
|
if len > self.len() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.len = len as u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if there are no elements.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
|
/// let mut versions = KeyFormatVersions::new();
|
||||||
|
///
|
||||||
|
/// assert_eq!(versions.is_empty(), true);
|
||||||
|
///
|
||||||
|
/// versions.push(2);
|
||||||
|
/// assert_eq!(versions.is_empty(), false);
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_empty(&self) -> bool { self.len() == 0 }
|
||||||
|
|
||||||
|
/// Removes the last element and returns it, or `None` if it is empty.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
|
/// let mut versions = KeyFormatVersions::new();
|
||||||
|
///
|
||||||
|
/// assert_eq!(versions.pop(), None);
|
||||||
|
///
|
||||||
|
/// versions.push(2);
|
||||||
|
/// assert_eq!(versions.pop(), Some(2));
|
||||||
|
/// assert_eq!(versions.is_empty(), true);
|
||||||
|
/// ```
|
||||||
|
pub fn pop(&mut self) -> Option<u8> {
|
||||||
|
if self.is_empty() {
|
||||||
|
None
|
||||||
} else {
|
} else {
|
||||||
self.0.push(value);
|
self.len -= 1;
|
||||||
|
Some(self.buffer[self.len()])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true`, if [`KeyFormatVersions`] has the default value of
|
/// Returns `true`, if it is either empty or has a length of 1 and the first
|
||||||
/// `vec![1]`.
|
/// element is 1.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use hls_m3u8::types::KeyFormatVersions;
|
/// # use hls_m3u8::types::KeyFormatVersions;
|
||||||
/// assert!(KeyFormatVersions::from(vec![1]).is_default());
|
/// let mut versions = KeyFormatVersions::new();
|
||||||
|
///
|
||||||
|
/// assert_eq!(versions.is_default(), true);
|
||||||
|
///
|
||||||
|
/// versions.push(1);
|
||||||
|
/// assert_eq!(versions.is_default(), true);
|
||||||
|
///
|
||||||
|
/// assert_eq!(KeyFormatVersions::default().is_default(), true);
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_default(&self) -> bool {
|
pub fn is_default(&self) -> bool {
|
||||||
//
|
self.is_empty() || (self.buffer[self.len().saturating_sub(1)] == 1 && self.len() == 1)
|
||||||
self.0 == vec![1] && self.0.len() == 1 || self.0.is_empty()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for KeyFormatVersions {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
if self.len() == other.len() {
|
||||||
|
// only compare the parts in the buffer, that are used:
|
||||||
|
self.as_ref() == self.as_ref()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for KeyFormatVersions {}
|
||||||
|
|
||||||
|
impl PartialOrd for KeyFormatVersions {
|
||||||
|
#[inline]
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(<Self as Ord>::cmp(self, other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for KeyFormatVersions {
|
||||||
|
#[inline]
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering { self.as_ref().cmp(other.as_ref()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for KeyFormatVersions {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
state.write_usize(self.len());
|
||||||
|
self.as_ref().hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for KeyFormatVersions {
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
fn as_ref(&self) -> &[u8] { &self.buffer[..self.len()] }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsMut<[u8]> for KeyFormatVersions {
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
fn as_mut(&mut self) -> &mut [u8] {
|
||||||
|
// this temporary variable is required, because the compiler does not resolve
|
||||||
|
// the borrow to it's value immediately, so there is a shared borrow and
|
||||||
|
// therefore no exclusive borrow can be made.
|
||||||
|
let len = self.len();
|
||||||
|
&mut self.buffer[..len]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extend<u8> for KeyFormatVersions {
|
||||||
|
fn extend<I: IntoIterator<Item = u8>>(&mut self, iter: I) {
|
||||||
|
for element in iter {
|
||||||
|
if self.remaining() == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.push(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Extend<&'a u8> for KeyFormatVersions {
|
||||||
|
fn extend<I: IntoIterator<Item = &'a u8>>(&mut self, iter: I) {
|
||||||
|
<Self as Extend<u8>>::extend(self, iter.into_iter().copied())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: SliceIndex<[u8]>> Index<I> for KeyFormatVersions {
|
||||||
|
type Output = I::Output;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(&self, index: I) -> &Self::Output { self.as_ref().index(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: SliceIndex<[u8]>> IndexMut<I> for KeyFormatVersions {
|
||||||
|
#[inline]
|
||||||
|
fn index_mut(&mut self, index: I) -> &mut Self::Output { self.as_mut().index_mut(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoIterator for KeyFormatVersions {
|
||||||
|
type IntoIter = IntoIter<u8>;
|
||||||
|
type Item = u8;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter { self.into() }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromIterator<u8> for KeyFormatVersions {
|
||||||
|
fn from_iter<I: IntoIterator<Item = u8>>(iter: I) -> Self {
|
||||||
|
let mut result = Self::default();
|
||||||
|
// an array like [0; 9] as empty
|
||||||
|
let mut is_empty = true;
|
||||||
|
|
||||||
|
for item in iter {
|
||||||
|
if item != 0 {
|
||||||
|
is_empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if result.remaining() == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_empty {
|
||||||
|
return Self::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> FromIterator<&'a u8> for KeyFormatVersions {
|
||||||
|
fn from_iter<I: IntoIterator<Item = &'a u8>>(iter: I) -> Self {
|
||||||
|
<Self as FromIterator<u8>>::from_iter(iter.into_iter().copied())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for KeyFormatVersions {
|
impl Default for KeyFormatVersions {
|
||||||
fn default() -> Self { Self(vec![1]) }
|
#[inline]
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
buffer: [0; 9],
|
||||||
|
len: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This tag requires [`ProtocolVersion::V5`].
|
/// This tag requires [`ProtocolVersion::V5`].
|
||||||
|
@ -76,41 +369,98 @@ impl FromStr for KeyFormatVersions {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
let mut result = unquote(input)
|
let mut result = Self::default();
|
||||||
|
|
||||||
|
for item in unquote(input)
|
||||||
.split('/')
|
.split('/')
|
||||||
.map(|v| v.parse().map_err(|e| Error::parse_int(v, e)))
|
.map(|v| v.parse().map_err(|e| Error::parse_int(v, e)))
|
||||||
.collect::<Result<Vec<_>, Error>>()?;
|
{
|
||||||
|
let item = item?;
|
||||||
|
|
||||||
|
if result.remaining() == 0 {
|
||||||
|
return Err(Error::custom(
|
||||||
|
"reached maximum number of elements in KeyFormatVersions",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
if result.is_empty() {
|
if result.is_empty() {
|
||||||
result.push(1);
|
result.push(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Self(result))
|
Ok(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for KeyFormatVersions {
|
impl fmt::Display for KeyFormatVersions {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if self.is_default() {
|
if self.is_default() || self.is_empty() {
|
||||||
return write!(f, "{}", quote("1"));
|
return write!(f, "{}", quote("1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(value) = self.0.iter().next() {
|
write!(f, "\"{}", self.buffer[0])?;
|
||||||
write!(f, "\"{}", value)?;
|
|
||||||
|
|
||||||
for value in self.0.iter().skip(1) {
|
for item in &self.buffer[1..self.len()] {
|
||||||
write!(f, "/{}", value)?;
|
write!(f, "/{}", item)?;
|
||||||
}
|
|
||||||
|
|
||||||
write!(f, "\"")?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write!(f, "\"")?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: IntoIterator<Item = usize>> From<I> for KeyFormatVersions {
|
impl<T: AsRef<[usize]>> From<T> for KeyFormatVersions {
|
||||||
fn from(value: I) -> Self { Self(value.into_iter().collect()) }
|
fn from(value: T) -> Self { Self::from_iter(value.as_ref().iter().map(|i| *i as u8)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Iterator` for [`KeyFormatVersions`].
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct IntoIter<T> {
|
||||||
|
buffer: [T; 9],
|
||||||
|
position: usize,
|
||||||
|
len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<KeyFormatVersions> for IntoIter<u8> {
|
||||||
|
fn from(value: KeyFormatVersions) -> Self {
|
||||||
|
Self {
|
||||||
|
buffer: value.buffer,
|
||||||
|
position: 0,
|
||||||
|
len: value.len(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> From<&'a KeyFormatVersions> for IntoIter<u8> {
|
||||||
|
fn from(value: &'a KeyFormatVersions) -> Self {
|
||||||
|
Self {
|
||||||
|
buffer: value.buffer,
|
||||||
|
position: 0,
|
||||||
|
len: value.len(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> ExactSizeIterator for IntoIter<T> {
|
||||||
|
fn len(&self) -> usize { self.len.saturating_sub(self.position) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy> ::core::iter::FusedIterator for IntoIter<T> {}
|
||||||
|
|
||||||
|
impl<T: Copy> Iterator for IntoIter<T> {
|
||||||
|
type Item = T;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.position == self.len {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.position += 1;
|
||||||
|
Some(self.buffer[self.position - 1])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -118,27 +468,200 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_hash() {
|
||||||
|
let mut hasher_left = std::collections::hash_map::DefaultHasher::new();
|
||||||
|
let mut hasher_right = std::collections::hash_map::DefaultHasher::new();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
KeyFormatVersions::from([1, 2, 3]).hash(&mut hasher_left),
|
||||||
|
KeyFormatVersions::from([1, 2, 3]).hash(&mut hasher_right)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(hasher_left.finish(), hasher_right.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_ord() {
|
||||||
|
assert_eq!(
|
||||||
|
KeyFormatVersions::from([1, 2]).cmp(&KeyFormatVersions::from([1, 2])),
|
||||||
|
Ordering::Equal
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
KeyFormatVersions::from([2]).cmp(&KeyFormatVersions::from([1, 2])),
|
||||||
|
Ordering::Greater
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
KeyFormatVersions::from([2, 3]).cmp(&KeyFormatVersions::from([1, 2])),
|
||||||
|
Ordering::Greater
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
KeyFormatVersions::from([]).cmp(&KeyFormatVersions::from([1, 2])),
|
||||||
|
Ordering::Less
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_partial_eq() {
|
||||||
|
let mut versions = KeyFormatVersions::from([1, 2, 3, 4, 5, 6]);
|
||||||
|
versions.truncate(3);
|
||||||
|
|
||||||
|
assert_eq!(versions, KeyFormatVersions::from([1, 2, 3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_as_ref() {
|
||||||
|
assert_eq!(KeyFormatVersions::new().as_ref(), &[]);
|
||||||
|
assert_eq!(KeyFormatVersions::from([1, 2, 3]).as_ref(), &[1, 2, 3]);
|
||||||
|
assert_eq!(KeyFormatVersions::from([]).as_ref(), &[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_as_mut() {
|
||||||
|
assert_eq!(KeyFormatVersions::new().as_mut(), &mut []);
|
||||||
|
assert_eq!(KeyFormatVersions::from([1, 2, 3]).as_mut(), &mut [1, 2, 3]);
|
||||||
|
assert_eq!(KeyFormatVersions::from([]).as_mut(), &mut []);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_index() {
|
||||||
|
// test index
|
||||||
|
assert_eq!(&KeyFormatVersions::new()[..], &[]);
|
||||||
|
assert_eq!(&KeyFormatVersions::from([1, 2, 3])[..2], &[1, 2]);
|
||||||
|
assert_eq!(&KeyFormatVersions::from([1, 2, 3])[1..2], &[2]);
|
||||||
|
assert_eq!(&KeyFormatVersions::from([1, 2, 3])[..], &[1, 2, 3]);
|
||||||
|
|
||||||
|
// test index_mut
|
||||||
|
assert_eq!(&mut KeyFormatVersions::new()[..], &mut []);
|
||||||
|
assert_eq!(&mut KeyFormatVersions::from([1, 2, 3])[..2], &mut [1, 2]);
|
||||||
|
assert_eq!(&mut KeyFormatVersions::from([1, 2, 3])[1..2], &mut [2]);
|
||||||
|
assert_eq!(&mut KeyFormatVersions::from([1, 2, 3])[..], &mut [1, 2, 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_extend() {
|
||||||
|
let mut versions = KeyFormatVersions::new();
|
||||||
|
versions.extend(&[1, 2, 3]);
|
||||||
|
|
||||||
|
assert_eq!(versions, KeyFormatVersions::from([1, 2, 3]));
|
||||||
|
|
||||||
|
versions.extend(&[1, 2, 3]);
|
||||||
|
assert_eq!(versions, KeyFormatVersions::from([1, 2, 3, 1, 2, 3]));
|
||||||
|
|
||||||
|
versions.extend(&[1, 2, 3, 4]);
|
||||||
|
assert_eq!(
|
||||||
|
versions,
|
||||||
|
KeyFormatVersions::from([1, 2, 3, 1, 2, 3, 1, 2, 3])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_default() {
|
||||||
|
assert_eq!(KeyFormatVersions::default(), KeyFormatVersions::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_into_iter() {
|
||||||
|
assert_eq!(KeyFormatVersions::new().into_iter().next(), None);
|
||||||
|
assert_eq!(KeyFormatVersions::new().into_iter().len(), 0);
|
||||||
|
|
||||||
|
let mut iterator = KeyFormatVersions::from([1, 2, 3, 4, 5]).into_iter();
|
||||||
|
|
||||||
|
assert_eq!(iterator.len(), 5);
|
||||||
|
assert_eq!(iterator.next(), Some(1));
|
||||||
|
|
||||||
|
assert_eq!(iterator.len(), 4);
|
||||||
|
assert_eq!(iterator.next(), Some(2));
|
||||||
|
|
||||||
|
assert_eq!(iterator.len(), 3);
|
||||||
|
assert_eq!(iterator.next(), Some(3));
|
||||||
|
|
||||||
|
assert_eq!(iterator.len(), 2);
|
||||||
|
assert_eq!(iterator.next(), Some(4));
|
||||||
|
|
||||||
|
assert_eq!(iterator.len(), 1);
|
||||||
|
assert_eq!(iterator.next(), Some(5));
|
||||||
|
|
||||||
|
assert_eq!(iterator.len(), 0);
|
||||||
|
assert_eq!(iterator.next(), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_from_iter() {
|
||||||
|
assert_eq!(
|
||||||
|
{
|
||||||
|
let mut result = KeyFormatVersions::new();
|
||||||
|
result.push(1);
|
||||||
|
result.push(2);
|
||||||
|
result.push(3);
|
||||||
|
result.push(4);
|
||||||
|
result
|
||||||
|
},
|
||||||
|
KeyFormatVersions::from_iter(&[1, 2, 3, 4])
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
{
|
||||||
|
let mut result = KeyFormatVersions::new();
|
||||||
|
result.push(0);
|
||||||
|
result.push(1);
|
||||||
|
result.push(2);
|
||||||
|
result.push(3);
|
||||||
|
result.push(4);
|
||||||
|
result
|
||||||
|
},
|
||||||
|
KeyFormatVersions::from_iter(&[0, 1, 2, 3, 4])
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(KeyFormatVersions::new(), KeyFormatVersions::from_iter(&[]));
|
||||||
|
|
||||||
|
assert_eq!(KeyFormatVersions::new(), KeyFormatVersions::from_iter(&[0]));
|
||||||
|
assert_eq!(
|
||||||
|
KeyFormatVersions::new(),
|
||||||
|
KeyFormatVersions::from_iter(&[0, 0])
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
{
|
||||||
|
let mut result = KeyFormatVersions::new();
|
||||||
|
result.push(0);
|
||||||
|
result.push(1);
|
||||||
|
result.push(2);
|
||||||
|
result.push(3);
|
||||||
|
result.push(4);
|
||||||
|
result.push(5);
|
||||||
|
result.push(6);
|
||||||
|
result.push(7);
|
||||||
|
result.push(8);
|
||||||
|
result
|
||||||
|
},
|
||||||
|
KeyFormatVersions::from_iter(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_display() {
|
fn test_display() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
KeyFormatVersions::from(vec![1, 2, 3, 4, 5]).to_string(),
|
KeyFormatVersions::from([1, 2, 3, 4, 5]).to_string(),
|
||||||
quote("1/2/3/4/5")
|
quote("1/2/3/4/5")
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(KeyFormatVersions::from(vec![]).to_string(), quote("1"));
|
assert_eq!(KeyFormatVersions::from([]).to_string(), quote("1"));
|
||||||
assert_eq!(KeyFormatVersions::new().to_string(), quote("1"));
|
assert_eq!(KeyFormatVersions::new().to_string(), quote("1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parser() {
|
fn test_parser() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
KeyFormatVersions::from(vec![1, 2, 3, 4, 5]),
|
KeyFormatVersions::from([1, 2, 3, 4, 5]),
|
||||||
quote("1/2/3/4/5").parse().unwrap()
|
quote("1/2/3/4/5").parse().unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(KeyFormatVersions::from(vec![1]), "1".parse().unwrap());
|
assert_eq!(KeyFormatVersions::from([1]), "1".parse().unwrap());
|
||||||
|
assert_eq!(KeyFormatVersions::from([1, 2]), "1/2".parse().unwrap());
|
||||||
|
|
||||||
assert_eq!(KeyFormatVersions::from(vec![1, 2]), "1/2".parse().unwrap());
|
|
||||||
assert!("1/b".parse::<KeyFormatVersions>().is_err());
|
assert!("1/b".parse::<KeyFormatVersions>().is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,28 +675,20 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_default() {
|
fn test_is_default() {
|
||||||
assert!(KeyFormatVersions::new().is_default());
|
assert_eq!(KeyFormatVersions::new().is_default(), true);
|
||||||
assert!(KeyFormatVersions::from(vec![]).is_default());
|
assert_eq!(KeyFormatVersions::default().is_default(), true);
|
||||||
assert!(!KeyFormatVersions::from(vec![1, 2, 3]).is_default());
|
|
||||||
|
assert_eq!(KeyFormatVersions::from([]).is_default(), true);
|
||||||
|
assert_eq!(KeyFormatVersions::from([1]).is_default(), true);
|
||||||
|
|
||||||
|
assert_eq!(KeyFormatVersions::from([1, 2, 3]).is_default(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_push() {
|
fn test_push() {
|
||||||
let mut key_format_versions = KeyFormatVersions::from(vec![]);
|
let mut key_format_versions = KeyFormatVersions::new();
|
||||||
|
|
||||||
key_format_versions.push(2);
|
key_format_versions.push(2);
|
||||||
assert_eq!(KeyFormatVersions::from(vec![2]), key_format_versions);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
assert_eq!(KeyFormatVersions::from([2]), key_format_versions);
|
||||||
fn test_deref() {
|
|
||||||
assert!(!KeyFormatVersions::new().is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_deref_mut() {
|
|
||||||
let mut key_format_versions = KeyFormatVersions::from(vec![1, 2, 3]);
|
|
||||||
key_format_versions.pop();
|
|
||||||
assert_eq!(key_format_versions, KeyFormatVersions::from(vec![1, 2]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue