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

A task for delayed IRI resolution.

This doesn’t heap-allocate until executed, and can estimate how much buffer is required to execute the resolution.

Implementations

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

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::resolve::FixedBaseResolver;
use iri_string::types::{IriAbsoluteStr, IriReferenceStr};

let base = IriAbsoluteStr::new("http://example.com/base/")?;
let resolver = FixedBaseResolver::new(base);

let reference = IriReferenceStr::new("../there")?;
let task = resolver.create_task(reference);

assert_eq!(task.allocate_and_write()?, "http://example.com/there");

Resolves 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 IRI referernce is unresolvable against the base.

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

Examples
use iri_string::resolve::FixedBaseResolver;
use iri_string::types::{IriAbsoluteStr, IriReferenceStr};

let base = IriAbsoluteStr::new("http://example.com/base/")?;
let resolver = FixedBaseResolver::new(base);

let reference = IriReferenceStr::new("../there")?;
let task = resolver.create_task(reference);

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

assert_eq!(resolved, "http://example.com/there");

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::resolve::{ErrorKind, FixedBaseResolver};
use iri_string::types::{IriAbsoluteStr, IriReferenceStr};

let base = IriAbsoluteStr::new("http://example.com/")?;
let resolver = FixedBaseResolver::new(base);

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

// 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

  • 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::resolve::FixedBaseResolver;
use iri_string::types::{IriAbsoluteStr, IriReferenceStr, IriString};

let base = IriAbsoluteStr::new("http://example.com/base-dir/")?;
let resolver = FixedBaseResolver::new(base);

let reference = IriReferenceStr::new("../there")?;
let task = resolver.create_task(reference);

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

    let resolved_long = task.write_to_iri_string(buf_long)?;
    assert_eq!(resolved_long, "http://example.com/there");
    assert_eq!(
        resolved_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 resolved_short = task.write_to_iri_string(buf_short)?;
    assert_eq!(resolved_short, "http://example.com/there");
    assert!(
        resolved_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::resolve::FixedBaseResolver;
use iri_string::types::{IriAbsoluteStr, IriReferenceStr};

let base = IriAbsoluteStr::new("http://example.com/base-dir/")?;
let resolver = FixedBaseResolver::new(base);

let reference = IriReferenceStr::new("../there")?;
let task = resolver.create_task(reference);

// 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/there");
    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/there");
    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::resolve::{Error, FixedBaseResolver};
use iri_string::types::{IriAbsoluteStr, IriReferenceStr};

let base = IriAbsoluteStr::new("http://example.com/base-dir/")?;
let resolver = FixedBaseResolver::new(base);

let reference = IriReferenceStr::new("../there")?;
let task = resolver.create_task(reference);

let mut buf = String::new();

let resolved_short: Result<_, Error> = task.try_append_to_std_string(&mut buf);
if let Ok(s) = resolved_short {
    assert_eq!(s, "http://example.com/there");
}

Returns the estimated maximum size required for IRI resolution.

With a buffer of the returned size, IRI resolution (and merge) would succeed without OOM error. The resolution 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::resolve::FixedBaseResolver;
use iri_string::types::{IriAbsoluteStr, IriReferenceStr};

let base = IriAbsoluteStr::new("http://example.com/base/")?;
let resolver = FixedBaseResolver::new(base);

let reference = IriReferenceStr::new("../there")?;
let task = resolver.create_task(reference);

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/there");

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 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.