Struct iri_string::resolve::ResolutionTask
source · [−]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");