[][src]Struct hrx::HrxArchive

pub struct HrxArchive {
    pub comment: Option<String>,
    pub entries: LinkedHashMap<HrxPath, HrxEntry>,
    // some fields omitted
}

A Human-Readable Archive, consisting of an optional comment and some entries, all separated by the boundary.

The archive boundary consists of a particular-length sequence of =s bounded with < and > on either side; that sequence must be consistent across the entirety of the archive, which means that no body (be it a comment or file contents) can contain a newline followed by the boundary.

However, there is no way to enforce that on the typesystem level, meaning that the entries and comments can be modified at will, so instead the archive will automatically check for boundary validity when

  1. changing the global boundary length (via set_boundary_length()) and
  2. serialising to an output stream (usually via serialise())

and return the paths to the erroneous (i.e. boundary-containing) bodys.

Fields

comment: Option<String>

Some optional metadata.

Cannot contain a newline followed by a boundary.

entries: LinkedHashMap<HrxPath, HrxEntry>

Some optional archive entries with their paths.

Methods

impl HrxArchive[src]

pub fn new(boundary_length: NonZeroUsize) -> HrxArchive[src]

Create an empty archive with the specified boundary length.

pub fn boundary_length(&self) -> NonZeroUsize[src]

Get the current boundary length, i.e. the amount of = characters in the boundary.

Examples

let arch_str = r#"<===> input.scss
ul {
  margin-left: 1em;
  li {
    list-style-type: none;
  }
}

<===> output.css
ul {
  margin-left: 1em;
}
ul li {
  list-style-type: none;
}"#;

let arch = HrxArchive::from_str(arch_str).unwrap();
assert_eq!(arch.boundary_length().get(), 3);

pub fn set_boundary_length(
    &mut self,
    new_len: NonZeroUsize
) -> Result<(), HrxError>
[src]

Set new boundary length, if valid.

Checks, whether any bodys within the archive contain the new boundary; if so – errors out with their paths, otherwise sets the boundary length to the specified value.

Examples

let arch_str = r#"<===> boundary-5.txt
This file contains a 5-length boundary:
<=====>
^ right there

<===>
This is a comment,
<=======>
which contains a 7-length boundary.

<===> fine.txt
This file consists of
multiple lines, but none of them
starts with any sort of boundary-like string"#;

let mut arch = HrxArchive::from_str(arch_str).unwrap();
assert_eq!(arch.boundary_length().get(), 3);

assert_eq!(arch.set_boundary_length(NonZeroUsize::new(4).unwrap()), Ok(()));
assert_eq!(arch.boundary_length().get(), 4);

assert_eq!(arch.set_boundary_length(NonZeroUsize::new(5).unwrap()),
           Err(ErroneousBodyPath::EntryData("boundary-5.txt".to_string()).into()));
assert_eq!(arch.boundary_length().get(), 4);

assert_eq!(arch.set_boundary_length(NonZeroUsize::new(6).unwrap()), Ok(()));
assert_eq!(arch.boundary_length().get(), 6);

assert_eq!(arch.set_boundary_length(NonZeroUsize::new(7).unwrap()),
           Err(ErroneousBodyPath::EntryComment("fine.txt".to_string()).into()));
assert_eq!(arch.boundary_length().get(), 6);

assert_eq!(arch.set_boundary_length(NonZeroUsize::new(8).unwrap()), Ok(()));
assert_eq!(arch.boundary_length().get(), 8);

pub fn validate_content(&self) -> Result<(), HrxError>[src]

Validate that no bodys contain a boundary or error out with the paths to the ones that do,

Examples

let mut arch = HrxArchive::new(NonZeroUsize::new(3).unwrap());
arch.comment = Some("Yeehaw! the comment\n<===>\n contains the boundary!".to_string());

arch.entries.insert("directory/dsc.txt".parse().unwrap(), HrxEntry {
    comment: None,
    data: HrxEntryData::File {
        body: Some("As does this file\n<===>, whew!".to_string()),
    },
});

assert_eq!(arch.validate_content(),
           Err(vec![ErroneousBodyPath::RootComment,
                    ErroneousBodyPath::EntryData("directory/dsc.txt".to_string())].into()));

pub fn serialise<W: Write>(
    &self,
    into: &mut W
) -> Result<(), Result<HrxError, IoError>>
[src]

Write the archive out to the specified output stream, after verification.

The compound result type is due to the fact that std::io::Error doesn't play well with having it in an enum variant.

Examples

Failed validation:

let mut arch = HrxArchive::new(NonZeroUsize::new(3).unwrap());
arch.comment = Some("Yeehaw! the comment\n<===>\n contains the boundary!".to_string());

let mut out = vec![];
assert_eq!(arch.serialise(&mut out).unwrap_err().unwrap(),
           ErroneousBodyPath::RootComment.into());
// Note how the returned result cannot be directly compared to,
// as a byproduct of `std::io::Error` being contained therein.

Generation:

let mut arch = HrxArchive::new(NonZeroUsize::new(5).unwrap());
arch.comment =
    Some("This is the archive comment, forthlaying its contents' description".to_string());

arch.entries.insert("directory".parse().unwrap(), HrxEntry {
    comment: Some("This directory contains files!".to_string()),
    data: HrxEntryData::Directory,
});

arch.entries.insert("directory/dsc.txt".parse().unwrap(), HrxEntry {
    comment:
        Some("This file forthlays the building blocks of any stable society".to_string()),
    data: HrxEntryData::File {
        body: Some("Коммунизм!\n".to_string()),
    },
});

let mut out = vec![];
arch.serialise(&mut out).unwrap();
assert_eq!(String::from_utf8(out).unwrap(), r#"<=====>
This directory contains files!
<=====> directory/
<=====>
This file forthlays the building blocks of any stable society
<=====> directory/dsc.txt
Коммунизм!

<=====>
This is the archive comment, forthlaying its contents' description"#);

Transserialisation:

let arch_str = r#"<===> input.scss
ul {
  margin-left: 1em;
  li {
    list-style-type: none;
  }
}

<===> output.css
ul {
  margin-left: 1em;
}
ul li {
  list-style-type: none;
}"#;

let arch = HrxArchive::from_str(arch_str).unwrap();

let mut out = vec![];
arch.serialise(&mut out).unwrap();
assert_eq!(String::from_utf8(out).unwrap(), arch_str);

Trait Implementations

impl Clone for HrxArchive[src]

impl Debug for HrxArchive[src]

impl Eq for HrxArchive[src]

impl FromStr for HrxArchive[src]

type Err = HrxError

The associated error which can be returned from parsing.

impl Hash for HrxArchive[src]

impl Ord for HrxArchive[src]

impl PartialEq<HrxArchive> for HrxArchive[src]

impl PartialOrd<HrxArchive> for HrxArchive[src]

impl StructuralEq for HrxArchive[src]

impl StructuralPartialEq for HrxArchive[src]

Auto Trait Implementations

impl RefUnwindSafe for HrxArchive

impl Send for HrxArchive

impl Sync for HrxArchive

impl Unpin for HrxArchive

impl UnwindSafe for HrxArchive

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.