pub struct NormalizationTask<'a, S> { /* private fields */ }
Expand description

IRI normalization/resolution task.

Implementations

Normalizes the IRI, and writes it to the newly allocated buffer.

Failures

This fails if:

  • buffer was not long enough, or
  • the resulting IRI referernce is unresolvable.

To see examples of unresolvable IRIs, visit the module documentation for resolve.

Examples
use iri_string::normalize::create_task;
use iri_string::types::IriStr;

let iri = IriStr::new("HTTP://e%78ample%2ecom/a/../slash%2fslash/\u{03B1}%ce%b1")?;
let task = create_task(iri.as_ref());

assert_eq!(
    task.allocate_and_write()?,
    "http://example.com/slash%2Fslash/\u{03B1}%CE%B1"
);

Normalizes the IRI, and writes it to the given byte slice.

To estimate how much memory is required (at most), use estimate_max_buf_size_for_resolution.

Failures

This fails if:

  • buffer was not long enough, or
  • the resulting IRI referernce is unresolvable.

To see examples of unresolvable IRIs, visit the module documentation for resolve.

Examples
use iri_string::normalize::create_task;
use iri_string::types::IriStr;

let iri = IriStr::new("HTTP://e%78ample%2ecom/a/../slash%2fslash/\u{03B1}%ce%b1")?;
let task = create_task(iri);

// Long enough!
let mut buf = [0_u8; 128];
let normalized = task.write_to_byte_slice(&mut buf[..])?;

assert_eq!(normalized, "http://example.com/slash%2Fslash/\u{03B1}%CE%B1");

This returns error when the buffer is not long enough for processing.

Note that it would be still not enough even if the buffer is long enough to store the result. During processing, the resolver might use more memory than the result. You can get maximum required buffer size by estimate_max_buf_size_for_resolution method.

use iri_string::normalize::{ErrorKind, NormalizationTask, create_task};
use iri_string::types::IriStr;

let iri = IriStr::new("http://example.com/a/b/c/d/e/../../../../../f")?;
const EXPECTED: &str = "http://example.com/f";
let task = create_task(iri);

// Buffer is too short for processing, even though it is long enough
// to store the result.
let mut buf = [0_u8; EXPECTED.len()];
let resolved = task.write_to_byte_slice(&mut buf[..]);
assert_eq!(
    resolved.map_err(|e| e.kind()),
    Err(ErrorKind::OutOfMemory),
    "failed due to not enough buffer size"
);
// You can retry writing if you have larger buffer,
// since `task` was not consumed.

Resolves the IRI, and writes it to the buffer inside the provided RiString.

This temporarily takes the ownership of the destination string buffer, since RiSting<S> always allocates (i.e. does not accept empty string as a default value) and the buffer cannot be replaced temporarily with the non-allocating default values. In order to make the function exception-safe, this cannot write to the &mut RiString<S> directly.

Failures

This fails if:

  • buffer was not long enough, or
  • the resulting IRI referernce is unresolvable.

To see examples of unresolvable IRIs, visit the module documentation for resolve.

Examples
use iri_string::normalize::create_task;
use iri_string::types::{IriStr, IriString};

let iri = IriStr::new("HTTP://e%78ample%2ecom/../../there")?;
let task = create_task(iri);

// Long buffer is reused.
{
    let buf_long = IriString::try_from("https://example.com/loooooooooooooooooooong-enough/sooooooooooooooo-long")?;
    let buf_long_capacity = buf_long.capacity();

    let normalized_long = task.write_to_iri_string(buf_long)?;
    assert_eq!(normalized_long, "http://example.com/there");
    assert_eq!(
        normalized_long.capacity(),
        buf_long_capacity,
        "the internal buffer was reused"
    );
}

// Short buffer will be extended or reallocated.
{
    let buf_short = IriString::try_from("foo:bar")?;
    let buf_short_capacity = buf_short.capacity();

    let normalized_short = task.write_to_iri_string(buf_short)?;
    assert_eq!(normalized_short, "http://example.com/there");
    assert!(
        normalized_short.capacity() >= buf_short_capacity,
        "the internal buffer would have been expanded"
    );
}

Resolves the IRI, and appends it to the buffer inside the provided String.

Failures

This fails if

  • memory allocation failed, or
  • the IRI referernce is unresolvable against the base.

To see examples of unresolvable IRIs, visit the documentation for resolve::Error.

Examples
use iri_string::normalize::create_task;
use iri_string::types::IriStr;

let iri = IriStr::new("HTTP://e%78ample%2ecom/a/../slash%2fslash/\u{03B1}%ce%b1")?;
let task = create_task(iri);

let mut buf = String::from("Result: ");

let result: Result<&IriStr, _> = task.try_append_to_std_string(&mut buf);
if let Ok(s) = result {
    assert_eq!(s, "http://example.com/slash%2Fslash/\u{03B1}%CE%B1");
    assert_eq!(buf, "Result: http://example.com/slash%2Fslash/\u{03B1}%CE%B1");
}

The buffer will be automatically expanded or reallocated when it was not long enough.

use iri_string::normalize::create_task;
use iri_string::types::IriStr;

let iri = IriStr::new("HTTP://e%78ample%2ecom/a/../slash%2fslash/\u{03B1}%ce%b1")?;
let task = create_task(iri);

// Long buffer is reused.
{
    let mut buf_long = String::with_capacity(128);
    let buf_long_capacity = buf_long.capacity();

    let resolved_long = task.append_to_std_string(&mut buf_long)?;
    assert_eq!(buf_long, "http://example.com/slash%2Fslash/\u{03B1}%CE%B1");
    assert_eq!(
        buf_long.capacity(),
        buf_long_capacity,
        "the internal buffer was reused"
    );
}

// Short buffer will be extended or reallocated.
{
    let mut buf_short = String::new();
    let buf_short_capacity = buf_short.capacity();
    assert_eq!(buf_short_capacity, 0, "String::new() does not heap-allocate");

    let resolved_short = task.append_to_std_string(&mut buf_short)?;
    assert_eq!(resolved_short, "http://example.com/slash%2Fslash/\u{03B1}%CE%B1");
    assert!(
        buf_short.capacity() >= buf_short_capacity,
        "the internal buffer would have been expanded"
    );
}

Resolves the IRI, and appends it to the buffer inside the provided String.

Failures

This fails if

  • memory allocation failed, or
  • the IRI referernce is unresolvable against the base.

To see examples of unresolvable IRIs, visit the documentation for resolve::Error.

Examples
use iri_string::normalize::create_task;
use iri_string::types::IriStr;

let iri = IriStr::new("HTTP://e%78ample%2ecom/a/../slash%2fslash/\u{03B1}%ce%b1")?;
let task = create_task(iri);

let mut buf = String::from("Result: ");

let result: Result<&IriStr, _> = task.try_append_to_std_string(&mut buf);
if let Ok(s) = result {
    assert_eq!(s, "http://example.com/slash%2Fslash/\u{03B1}%CE%B1");
    assert_eq!(buf, "Result: http://example.com/slash%2Fslash/\u{03B1}%CE%B1");
}

Returns the estimated maximum size required for IRI normalization/resolution.

With a buffer of the returned size, IRI normalization/resolution would succeed without OOM error. The operation may succeed with smaller buffer than this function estimates, but it is not guaranteed.

Note that this is O(N) operation (where N is input length).

Examples
use iri_string::normalize::create_task;
use iri_string::types::IriStr;

let iri = IriStr::new("HTTP://e%78ample%2ecom/a/../slash%2fslash/\u{03B1}%ce%b1")?;
let task = create_task(iri);

let max_size = task.estimate_max_buf_size_for_resolution();
let mut buf = vec![0_u8; max_size];
let resolved = task.write_to_byte_slice(&mut buf[..])?;

assert_eq!(resolved, "http://example.com/slash%2Fslash/\u{03B1}%CE%B1");

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.