Struct iri_string::normalize::NormalizationTask
source · [−]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
Auto Trait Implementations
impl<'a, S> RefUnwindSafe for NormalizationTask<'a, S>
impl<'a, S> Send for NormalizationTask<'a, S>
impl<'a, S> Sync for NormalizationTask<'a, S>
impl<'a, S> Unpin for NormalizationTask<'a, S>
impl<'a, S> UnwindSafe for NormalizationTask<'a, S>
Blanket Implementations
Mutably borrows from an owned value. Read more