gstreamer: caps: BuilderFull: prevent adding features if using any

Rework the API to statically prevent users adding extra features if the
builder has been created with builder_full_with_any_features(). It
doesn't make sense to add extra features if all are already included.
This commit is contained in:
Guillaume Desmottes 2020-01-10 11:20:27 +05:30 committed by Sebastian Dröge
parent 7f07bac0c7
commit c29a7638d3

View file

@ -9,6 +9,7 @@
use caps_features::*; use caps_features::*;
use miniobject::*; use miniobject::*;
use std::fmt; use std::fmt;
use std::marker::PhantomData;
use std::ptr; use std::ptr;
use std::str; use std::str;
use structure::*; use structure::*;
@ -34,17 +35,17 @@ impl Caps {
Builder::new(name) Builder::new(name)
} }
pub fn builder_full() -> BuilderFull { pub fn builder_full() -> BuilderFull<SomeFeatures> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
BuilderFull::new() BuilderFull::new()
} }
pub fn builder_full_with_features(features: CapsFeatures) -> BuilderFull { pub fn builder_full_with_features(features: CapsFeatures) -> BuilderFull<SomeFeatures> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
BuilderFull::new_with_features(features) BuilderFull::new_with_features(features)
} }
pub fn builder_full_with_any_features() -> BuilderFull { pub fn builder_full_with_any_features() -> BuilderFull<AnyFeatures> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
BuilderFull::new_with_any_features() BuilderFull::new_with_any_features()
} }
@ -578,19 +579,22 @@ impl<'a> Builder<'a> {
} }
} }
pub enum AnyFeatures {}
pub enum SomeFeatures {}
#[derive(Debug)] #[derive(Debug)]
pub struct BuilderFull { pub struct BuilderFull<T> {
caps: ::Caps, caps: ::Caps,
features: Option<CapsFeatures>, features: Option<CapsFeatures>,
any_features: bool, phantom: PhantomData<T>,
} }
impl BuilderFull { impl BuilderFull<SomeFeatures> {
fn new() -> Self { fn new() -> Self {
BuilderFull { BuilderFull {
caps: Caps::new_empty(), caps: Caps::new_empty(),
features: None, features: None,
any_features: false, phantom: PhantomData,
} }
} }
@ -598,33 +602,41 @@ impl BuilderFull {
BuilderFull { BuilderFull {
caps: Caps::new_empty(), caps: Caps::new_empty(),
features: Some(features), features: Some(features),
any_features: false, phantom: PhantomData,
} }
} }
pub fn structure_with_features(self, structure: Structure, features: CapsFeatures) -> Self {
self.append_structure(structure, Some(features))
}
pub fn structure_with_any_features(self, structure: Structure) -> Self {
self.append_structure(structure, Some(CapsFeatures::new_any()))
}
}
impl BuilderFull<AnyFeatures> {
fn new_with_any_features() -> Self { fn new_with_any_features() -> Self {
BuilderFull { BuilderFull {
caps: Caps::new_empty(), caps: Caps::new_empty(),
features: None, features: Some(CapsFeatures::new_any()),
any_features: true, phantom: PhantomData,
} }
} }
}
impl<T> BuilderFull<T> {
fn append_structure(mut self, structure: Structure, features: Option<CapsFeatures>) -> Self { fn append_structure(mut self, structure: Structure, features: Option<CapsFeatures>) -> Self {
let features = { let features = {
if self.any_features { match self.features {
Some(CapsFeatures::new_any()) None => features,
} else { Some(ref result) => {
match self.features { let mut result = result.clone();
None => features, match features {
Some(ref result) => { None => Some(result),
let mut result = result.clone(); Some(features) => {
match features { features.iter().for_each(|feat| result.add(feat));
None => Some(result), Some(result)
Some(features) => {
features.iter().for_each(|feat| result.add(feat));
Some(result)
}
} }
} }
} }
@ -642,14 +654,6 @@ impl BuilderFull {
self.append_structure(structure, None) self.append_structure(structure, None)
} }
pub fn structure_with_features(self, structure: Structure, features: CapsFeatures) -> Self {
self.append_structure(structure, Some(features))
}
pub fn structure_with_any_features(self, structure: Structure) -> Self {
self.append_structure(structure, Some(CapsFeatures::new_any()))
}
pub fn build(self) -> Caps { pub fn build(self) -> Caps {
self.caps self.caps
} }
@ -814,11 +818,7 @@ mod tests {
let caps = Caps::builder_full_with_any_features() let caps = Caps::builder_full_with_any_features()
.structure(Structure::builder("audio/x-raw").build()) .structure(Structure::builder("audio/x-raw").build())
.structure_with_features(
Structure::builder("video/x-raw").build(),
CapsFeatures::new(&["foo:bla", "foo:baz"]),
)
.build(); .build();
assert_eq!(caps.to_string(), "audio/x-raw(ANY); video/x-raw(ANY)"); assert_eq!(caps.to_string(), "audio/x-raw(ANY)");
} }
} }