use std::ops::{RangeFrom, RangeInclusive, RangeToInclusive};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct MediaTrackValueRangeCapability<T> {
#[cfg_attr(
feature = "serde",
serde(skip_serializing_if = "core::option::Option::is_none")
)]
pub min: Option<T>,
#[cfg_attr(
feature = "serde",
serde(skip_serializing_if = "core::option::Option::is_none")
)]
pub max: Option<T>,
}
impl<T> Default for MediaTrackValueRangeCapability<T> {
fn default() -> Self {
Self {
min: Default::default(),
max: Default::default(),
}
}
}
impl<T> From<RangeInclusive<T>> for MediaTrackValueRangeCapability<T> {
fn from(range: RangeInclusive<T>) -> Self {
let (min, max) = range.into_inner();
Self {
min: Some(min),
max: Some(max),
}
}
}
impl<T> From<RangeFrom<T>> for MediaTrackValueRangeCapability<T> {
fn from(range: RangeFrom<T>) -> Self {
Self {
min: Some(range.start),
max: None,
}
}
}
impl<T> From<RangeToInclusive<T>> for MediaTrackValueRangeCapability<T> {
fn from(range: RangeToInclusive<T>) -> Self {
Self {
min: None,
max: Some(range.end),
}
}
}
impl<T> MediaTrackValueRangeCapability<T> {
pub fn contains(&self, value: &T) -> bool
where
T: PartialOrd,
{
if let Some(ref min) = self.min {
if min > value {
return false;
}
}
if let Some(ref max) = self.max {
if max < value {
return false;
}
}
true
}
}
#[cfg(test)]
mod tests {
use super::*;
type Subject = MediaTrackValueRangeCapability<i64>;
#[test]
fn default() {
let subject = Subject::default();
assert_eq!(subject.min, None);
assert_eq!(subject.max, None);
}
mod from {
use super::*;
#[test]
fn range_inclusive() {
let subject = Subject::from(1..=5);
assert_eq!(subject.min, Some(1));
assert_eq!(subject.max, Some(5));
}
#[test]
fn range_from() {
let subject = Subject::from(1..);
assert_eq!(subject.min, Some(1));
assert_eq!(subject.max, None);
}
#[test]
fn range_to_inclusive() {
let subject = Subject::from(..=5);
assert_eq!(subject.min, None);
assert_eq!(subject.max, Some(5));
}
}
mod contains {
use super::*;
#[test]
fn default() {
let subject = Subject::default();
assert!(subject.contains(&0));
assert!(subject.contains(&1));
assert!(subject.contains(&5));
assert!(subject.contains(&6));
}
#[test]
fn from_range_inclusive() {
let subject = Subject::from(1..=5);
assert!(!subject.contains(&0));
assert!(subject.contains(&1));
assert!(subject.contains(&5));
assert!(!subject.contains(&6));
}
#[test]
fn from_range_from() {
let subject = Subject::from(1..);
assert!(!subject.contains(&0));
assert!(subject.contains(&1));
assert!(subject.contains(&5));
assert!(subject.contains(&6));
}
#[test]
fn from_range_to_inclusive() {
let subject = Subject::from(..=5);
assert!(subject.contains(&0));
assert!(subject.contains(&1));
assert!(subject.contains(&5));
assert!(!subject.contains(&6));
}
}
}
#[cfg(feature = "serde")]
#[cfg(test)]
mod serde_tests {
use crate::macros::test_serde_symmetry;
use super::*;
type Subject = MediaTrackValueRangeCapability<i64>;
#[test]
fn customized() {
let subject = Subject {
min: Some(12),
max: Some(34),
};
let json = serde_json::json!({
"min": 12,
"max": 34,
});
test_serde_symmetry!(subject: subject, json: json);
}
}