Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
255 changes: 255 additions & 0 deletions src/builders.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! Builders for the `sdp_types` `struct`s

#[derive(Debug)]
/// A [`crate::Origin`] builder.
pub struct Origin(crate::Origin);
impl Origin {
/// Construct an [`crate::Origin`] builder with "IN" as the `nettype`.
///
/// Use the specific setters to define the `user_name` and / or a different `nettype`.
pub fn new(
sess_id: impl ToString,
sess_version: u64,
addrtype: impl ToString,
unicast_address: impl ToString,
) -> Self {
Self(crate::Origin::new(
sess_id,
sess_version,
addrtype,
unicast_address,
))
}

pub fn username(mut self, username: impl ToString) -> Self {
self.0.set_username(username.to_string());
self
}

pub fn nettype(mut self, nettype: impl ToString) -> Self {
self.0.set_nettype(nettype);
self
}

pub fn build(self) -> crate::Origin {
self.0
}
}

#[derive(Debug)]
/// A [`crate::Time`] builder.
pub struct Time(crate::Time);
impl Time {
pub fn new(start_time: u64, stop_time: u64) -> Self {
Self(crate::Time::new(start_time, stop_time))
}

pub fn repeat(mut self, repeat: crate::Repeat) -> Self {
self.0.add_repeat(repeat);
self
}

pub fn build(self) -> crate::Time {
self.0
}
}

#[derive(Debug)]
/// A [`crate::Repeat`] builder.
pub struct Repeat(crate::Repeat);
impl Repeat {
pub fn new(repeat_interval: u64, active_duration: u64) -> Self {
Self(crate::Repeat::new(repeat_interval, active_duration))
}

pub fn offset(mut self, repeat: u64) -> Self {
self.0.add_offset(repeat);
self
}

pub fn build(self) -> crate::Repeat {
self.0
}
}

#[derive(Debug)]
/// A [`crate::Media`] builder.
pub struct Media(crate::Media);
impl Media {
pub fn new(media: impl ToString, port: u16, proto: impl ToString, fmt: impl ToString) -> Self {
Self(crate::Media::new(media, port, proto, fmt))
}

pub fn num_ports(mut self, num_ports: u16) -> Self {
self.0.set_num_ports(num_ports);
self
}

pub fn media_title(mut self, media_title: impl ToString) -> Self {
self.0.set_media_title(media_title);
self
}

pub fn connection(
mut self,
addrtype: impl ToString,
connection_address: impl ToString,
) -> Self {
self.0.add_connection(addrtype, connection_address);
self
}

pub fn connection_with_nettype(
mut self,
nettype: impl ToString,
addrtype: impl ToString,
connection_address: impl ToString,
) -> Self {
self.0
.add_connection_with_nettype(nettype, addrtype, connection_address);
self
}

pub fn bandwidth(mut self, bandwidth: crate::Bandwidth) -> Self {
self.0.add_bandwidth(bandwidth);
self
}

pub fn encryption_method(mut self, method: impl ToString) -> Self {
self.0.set_encryption_method(method);
self
}

pub fn encryption_key(mut self, method: impl ToString, encryption_key: impl ToString) -> Self {
self.0.set_encryption_key(method, encryption_key);
self
}

pub fn attribute(mut self, attribute: impl ToString) -> Self {
self.0.add_attribute(attribute);
self
}

pub fn attribute_with_value(mut self, attribute: impl ToString, value: impl ToString) -> Self {
self.0.add_attribute_with_value(attribute, value);
self
}

/// Adds an "rtpmap" compliant attribute with the provided values.
pub fn rtpmap(mut self, pt: u8, encoding_name: impl AsRef<str>, clock_rate: u32) -> Self {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this shouldn't be some kind of attribute builder

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you wish. Related to previous comment.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mean that this should be removed but should probably be some kind of specific attribute builder instead

self.0.add_rtpmap(pt, encoding_name, clock_rate);
self
}

/// Adds an "rtpmap" compliant attribute with the provided values.
pub fn rtpmap_with_params(
mut self,
pt: u8,
encoding_name: impl AsRef<str>,
clock_rate: u32,
encoding_parameter: impl ToString,
) -> Self {
self.0
.add_rtpmap_with_params(pt, encoding_name, clock_rate, encoding_parameter);
self
}

pub fn build(self) -> crate::Media {
self.0
}
}

#[derive(Debug)]
/// A [`crate::Session`] builder.
pub struct Session(crate::Session);
impl Session {
pub fn new(origin: crate::Origin, session_name: impl ToString) -> Self {
Self(crate::Session::new(origin, session_name))
}

pub fn session_description(mut self, session_description: impl ToString) -> Self {
self.0.set_session_description(session_description);
self
}

pub fn uri(mut self, uri: impl ToString) -> Self {
self.0.set_uri(uri);
self
}

pub fn email(mut self, email: impl ToString) -> Self {
self.0.add_email(email);
self
}

pub fn phone(mut self, phone: impl ToString) -> Self {
self.0.add_phone(phone);
self
}

pub fn connection(

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here and elsewhere I'm wondering why the builders don't take e.g. Connection directly here, but instead provide smaller setters

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I thought about mentioning it in the top comment, but then I forgot...

Connection, Attribute, Key and others have only two construction variants, so I thought it was more convenient and less verbose to include a direct setter in the builder. Ex:

    .connection(sdp_types::ADDRTYPE_IP4, outbound_addr)

instead of:

```rust
    .connection(sdp_types::Connection::new(sdp_types::ADDRTYPE_IP4, outbound_addr))

I could also use this for Origin btw.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense but maybe a generic one based on the struct would also make sense (if you want to copy over a Connection from some other session or so)?

mut self,
addrtype: impl ToString,
connection_address: impl ToString,
) -> Self {
self.0.set_connection(addrtype, connection_address);
self
}

pub fn connection_with_nettype(
mut self,
nettype: impl ToString,
addrtype: impl ToString,
connection_address: impl ToString,
) -> Self {
self.0
.set_connection_with_nettype(nettype, addrtype, connection_address);
self
}

pub fn bandwidth(mut self, bandwidth: crate::Bandwidth) -> Self {
self.0.add_bandwidth(bandwidth);
self
}

pub fn time(mut self, time: crate::Time) -> Self {
self.0.add_time(time);
self
}

pub fn time_zone(mut self, adjustment_time: u64, offset: i64) -> Self {
self.0.add_time_zone(adjustment_time, offset);
self
}

pub fn encryption_method(mut self, method: impl ToString) -> Self {
self.0.set_encryption_method(method);
self
}

pub fn encryption_key(mut self, method: impl ToString, encryption_key: impl ToString) -> Self {
self.0.set_encryption_key(method, encryption_key);
self
}

pub fn attribute(mut self, attribute: impl ToString) -> Self {
self.0.add_attribute(attribute);
self
}

pub fn attribute_with_value(mut self, attribute: impl ToString, value: impl ToString) -> Self {
self.0.add_attribute_with_value(attribute, value);
self
}

pub fn media(mut self, media: crate::Media) -> Self {
self.0.add_media(media);
self
}

pub fn build(self) -> crate::Session {
self.0
}
}
Loading
Loading