fluent_uri

Struct Builder

source
pub struct Builder<R, S> { /* private fields */ }
Expand description

A builder for URI/IRI (reference).

This struct is created by the builder associated functions on Uri, UriRef, Iri, and IriRef.

§Examples

Basic usage:

use fluent_uri::{component::Scheme, encoding::EStr, Uri};

const SCHEME_FOO: &Scheme = Scheme::new_or_panic("foo");

let uri = Uri::builder()
    .scheme(SCHEME_FOO)
    .authority_with(|b| {
        b.userinfo(EStr::new_or_panic("user"))
            .host(EStr::new_or_panic("example.com"))
            .port(8042)
    })
    .path(EStr::new_or_panic("/over/there"))
    .query(EStr::new_or_panic("name=ferret"))
    .fragment(EStr::new_or_panic("nose"))
    .build()
    .unwrap();

assert_eq!(
    uri.as_str(),
    "foo://user@example.com:8042/over/there?name=ferret#nose"
);

Note that EStr::new_or_panic panics on invalid input and should normally be used with constant strings. If you want to build a percent-encoded string from scratch, use EString instead.

§Constraints

Typestates are used to avoid misconfigurations, which puts the following constraints:

  • Components must be set from left to right, no repetition allowed.
  • Setting scheme is mandatory when building a URI/IRI.
  • Setting path is mandatory.
  • Methods userinfo, host, and port are only available within a call to authority_with.
  • Setting host is mandatory within a call to authority_with.

You may otherwise skip setting optional components (scheme, authority, userinfo, port, query, and fragment) with advance or set them optionally with optional.

The builder typestates are currently private. Please open an issue if it is a problem not being able to name the type of a builder.

Implementations§

source§

impl<R, S> Builder<R, S>

source

pub fn advance<T>(self) -> Builder<R, T>
where S: AdvanceTo<T>,

Advances the builder state, skipping optional components in between.

Variable rebinding may be necessary as this changes the type of the builder.

use fluent_uri::{component::Scheme, encoding::EStr, UriRef};

fn build(relative: bool) -> UriRef<String> {
    let b = UriRef::builder();
    let b = if relative {
        b.advance()
    } else {
        b.scheme(Scheme::new_or_panic("http"))
            .authority_with(|b| b.host(EStr::new_or_panic("example.com")))
    };
    b.path(EStr::new_or_panic("/foo")).build().unwrap()
}

assert_eq!(build(false).as_str(), "http://example.com/foo");
assert_eq!(build(true).as_str(), "/foo");
source

pub fn optional<F, V, T>(self, f: F, opt: Option<V>) -> Builder<R, T>
where F: FnOnce(Builder<R, S>, V) -> Builder<R, T>, S: AdvanceTo<T>,

Optionally calls a builder method with a value.

use fluent_uri::{encoding::EStr, Builder, UriRef};

let uri_ref = UriRef::builder()
    .path(EStr::new_or_panic("foo"))
    .optional(Builder::query, Some(EStr::new_or_panic("bar")))
    .optional(Builder::fragment, None)
    .build()
    .unwrap();

assert_eq!(uri_ref.as_str(), "foo?bar");
source§

impl<R, S: To<SchemeEnd>> Builder<R, S>

source

pub fn scheme(self, scheme: &Scheme) -> Builder<R, SchemeEnd>

Sets the scheme component.

Note that the scheme component is case-insensitive and its canonical form is lowercase. For consistency, you should only produce lowercase scheme names.

source§

impl<R: RiRef, S: To<AuthorityStart>> Builder<R, S>

source

pub fn authority_with<F, T>(self, f: F) -> Builder<R, AuthorityEnd>
where F: FnOnce(Builder<R, AuthorityStart>) -> Builder<R, T>, T: To<AuthorityEnd>,

Builds the authority component with the given function.

source

pub fn authority( self, authority: Authority<'_, R::UserinfoE, R::RegNameE>, ) -> Builder<R, AuthorityEnd>

Sets the authority component.

This method takes an Authority (for URI) or IAuthority (for IRI) as argument.

This method is normally used with an authority which is empty (Authority::EMPTY) or is obtained from a URI/IRI (reference). If you need to build an authority from its subcomponents (userinfo, host, and port), use authority_with instead.

§Examples
use fluent_uri::{
    component::{Authority, Scheme},
    encoding::EStr,
    Builder, Uri,
};

let uri = Uri::builder()
    .scheme(Scheme::new_or_panic("file"))
    .authority(Authority::EMPTY)
    .path(EStr::new_or_panic("/path/to/file"))
    .build()
    .unwrap();

assert_eq!(uri, "file:///path/to/file");

let auth = Uri::parse("foo://user@example.com:8042")?
    .authority()
    .unwrap();
let uri = Uri::builder()
    .scheme(Scheme::new_or_panic("http"))
    .authority(auth)
    .path(EStr::EMPTY)
    .build()
    .unwrap();

assert_eq!(uri, "http://user@example.com:8042");
source§

impl<R: RiRef, S: To<UserinfoEnd>> Builder<R, S>

source

pub fn userinfo(self, userinfo: &EStr<R::UserinfoE>) -> Builder<R, UserinfoEnd>

Sets the userinfo subcomponent of authority.

This method takes an &EStr<Userinfo> (for URI) or &EStr<IUserinfo> (for IRI) as argument.

source§

impl<R: RiRef, S: To<HostEnd>> Builder<R, S>

source

pub fn host<'a>( self, host: impl AsHost<'a> + WithEncoder<R::RegNameE>, ) -> Builder<R, HostEnd>

Sets the host subcomponent of authority.

This method takes either an Ipv4Addr, Ipv6Addr, IpAddr, &EStr<RegName> (for URI) or &EStr<IRegName> (for IRI) as argument. Crate feature net is required for this method to take an IP address as argument.

If the contents of an input EStr slice matches the IPv4address ABNF rule defined in Section 3.2.2 of RFC 3986, the resulting URI/IRI (reference) will output a Host::Ipv4 variant instead.

Note that ASCII characters within a host are case-insensitive. For consistency, you should only produce normalized hosts.

§Examples
use fluent_uri::{component::Host, encoding::EStr, UriRef};

let uri_ref = UriRef::builder()
    .authority_with(|b| b.host(EStr::new_or_panic("127.0.0.1")))
    .path(EStr::EMPTY)
    .build()
    .unwrap();

assert!(matches!(uri_ref.authority().unwrap().host_parsed(), Host::Ipv4 { .. }));
source§

impl<R, S: To<PortEnd>> Builder<R, S>

source

pub fn port(self, port: impl AsPort) -> Builder<R, PortEnd>

Sets the port subcomponent of authority.

This method takes either a u16 or &EStr<Port> as argument.

For consistency, you should not produce an empty port.

source§

impl<R: RiRef, S: To<PathEnd>> Builder<R, S>

source

pub fn path(self, path: &EStr<R::PathE>) -> Builder<R, PathEnd>

Sets the path component.

This method takes an &EStr<Path> (for URI) or &EStr<IPath> (for IRI) as argument.

source§

impl<R: RiRef, S: To<QueryEnd>> Builder<R, S>

source

pub fn query(self, query: &EStr<R::QueryE>) -> Builder<R, QueryEnd>

Sets the query component.

This method takes an &EStr<Query> (for URI) or &EStr<IQuery> (for IRI) as argument.

source§

impl<R: RiRef, S: To<FragmentEnd>> Builder<R, S>

source

pub fn fragment(self, fragment: &EStr<R::FragmentE>) -> Builder<R, FragmentEnd>

Sets the fragment component.

This method takes an &EStr<Fragment> (for URI) or &EStr<IFragment> (for IRI) as argument.

source§

impl<R: RiRef<Val = String>, S: To<End>> Builder<R, S>

source

pub fn build(self) -> Result<R, BuildError>

Builds the URI/IRI (reference).

§Errors

Returns Err if any of the following conditions is not met.

  • When authority is present, the path must either be empty or start with '/'.
  • When authority is not present, the path cannot start with "//".
  • In a relative-path reference, the first path segment cannot contain ':'.

Auto Trait Implementations§

§

impl<R, S> Freeze for Builder<R, S>

§

impl<R, S> RefUnwindSafe for Builder<R, S>

§

impl<R, S> Send for Builder<R, S>
where R: Send, S: Send,

§

impl<R, S> Sync for Builder<R, S>
where R: Sync, S: Sync,

§

impl<R, S> Unpin for Builder<R, S>
where R: Unpin, S: Unpin,

§

impl<R, S> UnwindSafe for Builder<R, S>
where R: UnwindSafe, S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.