diff --git a/.lock b/.lock new file mode 100644 index 0000000..e69de29 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/ba2/all.html b/ba2/all.html new file mode 100644 index 0000000..98b2c69 --- /dev/null +++ b/ba2/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Functions

Type Aliases

\ No newline at end of file diff --git a/ba2/enum.CompressionResult.html b/ba2/enum.CompressionResult.html new file mode 100644 index 0000000..e9a1b6c --- /dev/null +++ b/ba2/enum.CompressionResult.html @@ -0,0 +1,20 @@ +CompressionResult in ba2 - Rust
pub enum CompressionResult {
+    Compressed,
+    Decompressed,
+}
Expand description

Indicates whether the operation should finish by compressing the data or not.

+

Variants§

§

Compressed

The data will finish in a compressed state.

+
§

Decompressed

The data will finish in a decompressed state.

+

Trait Implementations§

source§

impl Clone for CompressionResult

source§

fn clone(&self) -> CompressionResult

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CompressionResult

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionResult

source§

fn default() -> CompressionResult

Returns the “default value” for a type. Read more
source§

impl PartialEq for CompressionResult

source§

fn eq(&self, other: &CompressionResult) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for CompressionResult

source§

impl Eq for CompressionResult

source§

impl StructuralEq for CompressionResult

source§

impl StructuralPartialEq for CompressionResult

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/enum.FileFormat.html b/ba2/enum.FileFormat.html new file mode 100644 index 0000000..8bcd619 --- /dev/null +++ b/ba2/enum.FileFormat.html @@ -0,0 +1,19 @@ +FileFormat in ba2 - Rust

Enum ba2::FileFormat

source ·
pub enum FileFormat {
+    TES3,
+    TES4,
+    FO4,
+}
Expand description

The file format for a given archive.

+

Variants§

§

TES3

§

TES4

§

FO4

Trait Implementations§

source§

impl Clone for FileFormat

source§

fn clone(&self) -> FileFormat

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for FileFormat

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for FileFormat

source§

fn eq(&self, other: &FileFormat) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for FileFormat

source§

impl Eq for FileFormat

source§

impl StructuralEq for FileFormat

source§

impl StructuralPartialEq for FileFormat

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fn.guess_format.html b/ba2/fn.guess_format.html new file mode 100644 index 0000000..33420e5 --- /dev/null +++ b/ba2/fn.guess_format.html @@ -0,0 +1,4 @@ +guess_format in ba2 - Rust

Function ba2::guess_format

source ·
pub fn guess_format<In>(source: &mut In) -> Option<FileFormat>where
+    In: ?Sized + Read,
Expand description

Guesses the archive format for a given source.

+

This function does not guarantee that the given source constitutes a well-formed archive of the deduced format. It merely remarks that if the file were a well-formed archive, it would be of the deduced format.

+
\ No newline at end of file diff --git a/ba2/fo4/archive/struct.Archive.html b/ba2/fo4/archive/struct.Archive.html new file mode 100644 index 0000000..2630c1d --- /dev/null +++ b/ba2/fo4/archive/struct.Archive.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.Archive.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/archive/struct.Key.html b/ba2/fo4/archive/struct.Key.html new file mode 100644 index 0000000..70bd1b0 --- /dev/null +++ b/ba2/fo4/archive/struct.Key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.ArchiveKey.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/archive/struct.Options.html b/ba2/fo4/archive/struct.Options.html new file mode 100644 index 0000000..b61baf2 --- /dev/null +++ b/ba2/fo4/archive/struct.Options.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.ArchiveOptions.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/archive/struct.OptionsBuilder.html b/ba2/fo4/archive/struct.OptionsBuilder.html new file mode 100644 index 0000000..e4f6aae --- /dev/null +++ b/ba2/fo4/archive/struct.OptionsBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.ArchiveOptionsBuilder.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/chunk/struct.Chunk.html b/ba2/fo4/chunk/struct.Chunk.html new file mode 100644 index 0000000..85610dd --- /dev/null +++ b/ba2/fo4/chunk/struct.Chunk.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.Chunk.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/chunk/struct.CompressionOptions.html b/ba2/fo4/chunk/struct.CompressionOptions.html new file mode 100644 index 0000000..9c304d8 --- /dev/null +++ b/ba2/fo4/chunk/struct.CompressionOptions.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.ChunkCompressionOptions.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/chunk/struct.CompressionOptionsBuilder.html b/ba2/fo4/chunk/struct.CompressionOptionsBuilder.html new file mode 100644 index 0000000..8931e8f --- /dev/null +++ b/ba2/fo4/chunk/struct.CompressionOptionsBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.ChunkCompressionOptionsBuilder.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/enum.CompressionFormat.html b/ba2/fo4/enum.CompressionFormat.html new file mode 100644 index 0000000..1a7f8b5 --- /dev/null +++ b/ba2/fo4/enum.CompressionFormat.html @@ -0,0 +1,21 @@ +CompressionFormat in ba2::fo4 - Rust
pub enum CompressionFormat {
+    Zip,
+    LZ4,
+}
Expand description

A list of all compression methods supported by the ba2 format.

+

Variants§

§

Zip

The default compression format, compatible with all games that utilize the ba2 format.

+
§

LZ4

A more specialized format leveraging lz4’s fast decompression to improve streaming time.

+

Only compatible with Starfield or later.

+

Trait Implementations§

source§

impl Clone for CompressionFormat

source§

fn clone(&self) -> CompressionFormat

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CompressionFormat

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionFormat

source§

fn default() -> CompressionFormat

Returns the “default value” for a type. Read more
source§

impl PartialEq for CompressionFormat

source§

fn eq(&self, other: &CompressionFormat) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for CompressionFormat

source§

impl Eq for CompressionFormat

source§

impl StructuralEq for CompressionFormat

source§

impl StructuralPartialEq for CompressionFormat

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/enum.CompressionLevel.html b/ba2/fo4/enum.CompressionLevel.html new file mode 100644 index 0000000..3ac0a8d --- /dev/null +++ b/ba2/fo4/enum.CompressionLevel.html @@ -0,0 +1,26 @@ +CompressionLevel in ba2::fo4 - Rust
pub enum CompressionLevel {
+    FO4,
+    FO4Xbox,
+    SF,
+}
Expand description

Specifies the compression level to use when compressing data.

+

Only compatible with CompressionFormat::Zip.

+

Variants§

§

FO4

Fallout 4.

+
§

FO4Xbox

Fallout 4 on the xbox.

+

Uses a smaller windows size, but higher a compression level to yield a higher compression ratio.

+
§

SF

Starfield.

+

Uses a custom DEFLATE algorithm with zlib wrapper to obtain a good compression ratio.

+

Implementations§

source§

impl CompressionLevel

source

pub const FO76: Self = Self::FO4

Fallout 76.

+

Trait Implementations§

source§

impl Clone for CompressionLevel

source§

fn clone(&self) -> CompressionLevel

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CompressionLevel

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionLevel

source§

fn default() -> CompressionLevel

Returns the “default value” for a type. Read more
source§

impl PartialEq for CompressionLevel

source§

fn eq(&self, other: &CompressionLevel) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for CompressionLevel

source§

impl Eq for CompressionLevel

source§

impl StructuralEq for CompressionLevel

source§

impl StructuralPartialEq for CompressionLevel

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/enum.Error.html b/ba2/fo4/enum.Error.html new file mode 100644 index 0000000..3c02bd1 --- /dev/null +++ b/ba2/fo4/enum.Error.html @@ -0,0 +1,31 @@ +Error in ba2::fo4 - Rust

Enum ba2::fo4::Error

source ·
#[non_exhaustive]
pub enum Error { +
Show 15 variants AlreadyCompressed, + AlreadyDecompressed, + DecompressionSizeMismatch { + expected: usize, + actual: usize, + }, + DX10(HResultError), + FormatMismatch, + IntegralOverflow, + IntegralTruncation, + InvalidChunkSentinel(u32), + InvalidChunkSize(u16), + InvalidFormat(u32), + InvalidMagic(u32), + InvalidVersion(u32), + Io(Error), + LZ4(Error), + NotImplemented, +
}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

AlreadyCompressed

§

AlreadyDecompressed

§

DecompressionSizeMismatch

Fields

§expected: usize
§actual: usize
§

DX10(HResultError)

§

FormatMismatch

§

IntegralOverflow

§

IntegralTruncation

§

InvalidChunkSentinel(u32)

§

InvalidChunkSize(u16)

§

InvalidFormat(u32)

§

InvalidMagic(u32)

§

InvalidVersion(u32)

§

Io(Error)

§

LZ4(Error)

§

NotImplemented

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<HResultError> for Error

source§

fn from(source: HResultError) -> Self

Converts to this type from the input type.
source§

impl From<Infallible> for Error

source§

fn from(source: Infallible) -> Self

Converts to this type from the input type.
source§

impl From<TryFromIntError> for Error

source§

fn from(_: TryFromIntError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/enum.FileHeader.html b/ba2/fo4/enum.FileHeader.html new file mode 100644 index 0000000..e76998a --- /dev/null +++ b/ba2/fo4/enum.FileHeader.html @@ -0,0 +1,20 @@ +FileHeader in ba2::fo4 - Rust

Enum ba2::fo4::FileHeader

source ·
pub enum FileHeader {
+    GNRL,
+    DX10(DX10),
+    GNMF(GNMF),
+}
Expand description

Optionally present file header.

+

The header variant must match the archive Format when writing.

+

Variants§

§

GNRL

§

DX10(DX10)

§

GNMF(GNMF)

Trait Implementations§

source§

impl Clone for Header

source§

fn clone(&self) -> Header

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Header

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Header

source§

fn default() -> Header

Returns the “default value” for a type. Read more
source§

impl From<DX10> for Header

source§

fn from(value: DX10) -> Self

Converts to this type from the input type.
source§

impl From<GNMF> for Header

source§

fn from(value: GNMF) -> Self

Converts to this type from the input type.
source§

impl PartialEq for Header

source§

fn eq(&self, other: &Header) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Header

source§

impl StructuralEq for Header

source§

impl StructuralPartialEq for Header

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/enum.Format.html b/ba2/fo4/enum.Format.html new file mode 100644 index 0000000..4db0305 --- /dev/null +++ b/ba2/fo4/enum.Format.html @@ -0,0 +1,22 @@ +Format in ba2::fo4 - Rust

Enum ba2::fo4::Format

source ·
pub enum Format {
+    GNRL,
+    DX10,
+    GNMF,
+}
Expand description

Represents the file format for an archive.

+

Variants§

§

GNRL

A GNRL archive can contain any kind of file.

+
§

DX10

A DX10 archive can only contain .dds files (Microsoft DirectX).

+
§

GNMF

A GNMF archive can only contain .gnf files (Sony GNM).

+

Trait Implementations§

source§

impl Clone for Format

source§

fn clone(&self) -> Format

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Format

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Format

source§

fn default() -> Format

Returns the “default value” for a type. Read more
source§

impl PartialEq for Format

source§

fn eq(&self, other: &Format) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Format

source§

impl Eq for Format

source§

impl StructuralEq for Format

source§

impl StructuralPartialEq for Format

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/enum.Version.html b/ba2/fo4/enum.Version.html new file mode 100644 index 0000000..1394459 --- /dev/null +++ b/ba2/fo4/enum.Version.html @@ -0,0 +1,27 @@ +Version in ba2::fo4 - Rust

Enum ba2::fo4::Version

source ·
pub enum Version {
+    v1 = 1,
+    v2 = 2,
+    v3 = 3,
+}
Expand description

Indicates the version of an archive.

+

Variants§

§

v1 = 1

Initial format introduced in Fallout 4.

+
§

v2 = 2

Intoduced in Starfield.

+
§

v3 = 3

Intoduced in Starfield.

+

Trait Implementations§

source§

impl Clone for Version

source§

fn clone(&self) -> Version

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Version

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Version

source§

fn default() -> Version

Returns the “default value” for a type. Read more
source§

impl Ord for Version

source§

fn cmp(&self, other: &Version) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Version

source§

fn eq(&self, other: &Version) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Version

source§

fn partial_cmp(&self, other: &Version) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Version

source§

impl Eq for Version

source§

impl StructuralEq for Version

source§

impl StructuralPartialEq for Version

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/file/enum.Header.html b/ba2/fo4/file/enum.Header.html new file mode 100644 index 0000000..194d15b --- /dev/null +++ b/ba2/fo4/file/enum.Header.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/enum.FileHeader.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.CapacityError.html b/ba2/fo4/file/struct.CapacityError.html new file mode 100644 index 0000000..5d900c3 --- /dev/null +++ b/ba2/fo4/file/struct.CapacityError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.FileCapacityError.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.DX10.html b/ba2/fo4/file/struct.DX10.html new file mode 100644 index 0000000..b433ff4 --- /dev/null +++ b/ba2/fo4/file/struct.DX10.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.DX10Header.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.File.html b/ba2/fo4/file/struct.File.html new file mode 100644 index 0000000..68cb322 --- /dev/null +++ b/ba2/fo4/file/struct.File.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.File.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.GNMF.html b/ba2/fo4/file/struct.GNMF.html new file mode 100644 index 0000000..35d194a --- /dev/null +++ b/ba2/fo4/file/struct.GNMF.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.GNMFHeader.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.ReadOptions.html b/ba2/fo4/file/struct.ReadOptions.html new file mode 100644 index 0000000..78aa95b --- /dev/null +++ b/ba2/fo4/file/struct.ReadOptions.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.FileReadOptions.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.ReadOptionsBuilder.html b/ba2/fo4/file/struct.ReadOptionsBuilder.html new file mode 100644 index 0000000..fa16b51 --- /dev/null +++ b/ba2/fo4/file/struct.ReadOptionsBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.FileReadOptionsBuilder.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.WriteOptions.html b/ba2/fo4/file/struct.WriteOptions.html new file mode 100644 index 0000000..c9287c5 --- /dev/null +++ b/ba2/fo4/file/struct.WriteOptions.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.FileWriteOptions.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/file/struct.WriteOptionsBuilder.html b/ba2/fo4/file/struct.WriteOptionsBuilder.html new file mode 100644 index 0000000..6d51cc5 --- /dev/null +++ b/ba2/fo4/file/struct.WriteOptionsBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.FileWriteOptionsBuilder.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/fn.hash_file.html b/ba2/fo4/fn.hash_file.html new file mode 100644 index 0000000..87843ba --- /dev/null +++ b/ba2/fo4/fn.hash_file.html @@ -0,0 +1,2 @@ +hash_file in ba2::fo4 - Rust

Function ba2::fo4::hash_file

source ·
pub fn hash_file(path: &BStr) -> (FileHash, BString)
Expand description

Produces a hash using the given path.

+
\ No newline at end of file diff --git a/ba2/fo4/fn.hash_file_in_place.html b/ba2/fo4/fn.hash_file_in_place.html new file mode 100644 index 0000000..5f23067 --- /dev/null +++ b/ba2/fo4/fn.hash_file_in_place.html @@ -0,0 +1,3 @@ +hash_file_in_place in ba2::fo4 - Rust

Function ba2::fo4::hash_file_in_place

source ·
pub fn hash_file_in_place(path: &mut BString) -> FileHash
Expand description

Produces a hash using the given path.

+

The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.

+
\ No newline at end of file diff --git a/ba2/fo4/hashing/fn.hash_file.html b/ba2/fo4/hashing/fn.hash_file.html new file mode 100644 index 0000000..8f5f60a --- /dev/null +++ b/ba2/fo4/hashing/fn.hash_file.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/fn.hash_file.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/hashing/fn.hash_file_in_place.html b/ba2/fo4/hashing/fn.hash_file_in_place.html new file mode 100644 index 0000000..b579a20 --- /dev/null +++ b/ba2/fo4/hashing/fn.hash_file_in_place.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/fn.hash_file_in_place.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/hashing/struct.FileHash.html b/ba2/fo4/hashing/struct.FileHash.html new file mode 100644 index 0000000..a24152b --- /dev/null +++ b/ba2/fo4/hashing/struct.FileHash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.FileHash.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/hashing/struct.Hash.html b/ba2/fo4/hashing/struct.Hash.html new file mode 100644 index 0000000..22689c4 --- /dev/null +++ b/ba2/fo4/hashing/struct.Hash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/fo4/struct.Hash.html...

+ + + \ No newline at end of file diff --git a/ba2/fo4/index.html b/ba2/fo4/index.html new file mode 100644 index 0000000..f1430de --- /dev/null +++ b/ba2/fo4/index.html @@ -0,0 +1,38 @@ +ba2::fo4 - Rust

Module ba2::fo4

source ·
Expand description

Fallout 4

+

“Good morning! Vault-Tec calling! … You can’t begin to know how happy I am to finally speak with you. I’ve been trying for days. It’s a matter of utmost urgency, I assure you.”

+

This format is the latest iteration, having debuted with Fallout 4. It primarily uses zlib for compression, but Starfield has introduced lz4 into the mix. Unlike previous formats, texture files are now split into chunks to enable streaming mips at a more granular level.

+

Reading

+
use ba2::{
+    fo4::{Archive, ArchiveKey, FileWriteOptions},
+    prelude::*,
+};
+use std::{fs, path::Path};
+
+fn example() -> Option<()> {
+    let path = Path::new(r"path/to/fallout4/Data/Fallout4 - Interface.ba2");
+    let (archive, meta) = Archive::read(path).ok()?;
+    let key: ArchiveKey = b"Interface/HUDMenu.swf".into();
+    let file = archive.get(&key)?;
+    let mut dst = fs::File::create("HUDMenu.swf").ok()?;
+    let options: FileWriteOptions = meta.into();
+    file.write(&mut dst, &options).ok()?;
+    Some(())
+}
+

Writing

+
use ba2::{
+    fo4::{Archive, ArchiveKey, ArchiveOptions, Chunk, File},
+    prelude::*,
+};
+use std::fs;
+
+fn example() -> Option<()> {
+    let chunk = Chunk::from_decompressed(b"Hello world!\n");
+    let file: File = [chunk].into_iter().collect();
+    let key: ArchiveKey = b"hello.txt".into();
+    let archive: Archive = [(key, file)].into_iter().collect();
+    let mut dst = fs::File::create("example.ba2").ok()?;
+    let options = ArchiveOptions::default();
+    archive.write(&mut dst, &options).ok()?;
+    Some(())
+}
+

Structs

Enums

Functions

Type Aliases

\ No newline at end of file diff --git a/ba2/fo4/sidebar-items.js b/ba2/fo4/sidebar-items.js new file mode 100644 index 0000000..5a122ee --- /dev/null +++ b/ba2/fo4/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CompressionFormat","CompressionLevel","Error","FileHeader","Format","Version"],"fn":["hash_file","hash_file_in_place"],"struct":["Archive","ArchiveKey","ArchiveOptions","ArchiveOptionsBuilder","Chunk","ChunkCompressionOptions","ChunkCompressionOptionsBuilder","DX10Header","File","FileCapacityError","FileHash","FileReadOptions","FileReadOptionsBuilder","FileWriteOptions","FileWriteOptionsBuilder","GNMFHeader","Hash"],"type":["Result"]}; \ No newline at end of file diff --git a/ba2/fo4/struct.Archive.html b/ba2/fo4/struct.Archive.html new file mode 100644 index 0000000..5dfa3b6 --- /dev/null +++ b/ba2/fo4/struct.Archive.html @@ -0,0 +1,26 @@ +Archive in ba2::fo4 - Rust

Struct ba2::fo4::Archive

source ·
pub struct Archive<'bytes> { /* private fields */ }
Expand description

Represents the FO4 revision of the ba2 format.

+

Implementations§

source§

impl<'bytes> Archive<'bytes>

source

pub fn clear(&mut self)

source

pub fn get<K>(&self, key: &K) -> Option<&File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn get_key_value<K>(&self, key: &K) -> Option<(&Key<'bytes>, &File<'bytes>)>where + K: Borrow<FileHash>,

source

pub fn get_mut<K>(&mut self, key: &K) -> Option<&mut File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn insert<K>(&mut self, key: K, value: File<'bytes>) -> Option<File<'bytes>>where + K: Into<Key<'bytes>>,

source

pub fn is_empty(&self) -> bool

source

pub fn iter(&self) -> impl Iterator<Item = (&Key<'bytes>, &File<'bytes>)>

source

pub fn iter_mut( + &mut self +) -> impl Iterator<Item = (&Key<'bytes>, &mut File<'bytes>)>

source

pub fn keys(&self) -> impl Iterator<Item = &Key<'bytes>>

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source

pub fn remove<K>(&mut self, key: &K) -> Option<File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn remove_entry<K>( + &mut self, + key: &K +) -> Option<(Key<'bytes>, File<'bytes>)>where + K: Borrow<FileHash>,

source

pub fn values(&self) -> impl Iterator<Item = &File<'bytes>>

source

pub fn values_mut(&mut self) -> impl Iterator<Item = &mut File<'bytes>>

source§

impl<'bytes> Archive<'bytes>

source

pub fn write<Out>(&self, stream: &mut Out, options: &Options) -> Result<()>where + Out: ?Sized + Write,

Trait Implementations§

source§

impl<'bytes> Clone for Archive<'bytes>

source§

fn clone(&self) -> Archive<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Archive<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Archive<'bytes>

source§

fn default() -> Archive<'bytes>

Returns the “default value” for a type. Read more
source§

impl<'bytes> FromIterator<(Key<'bytes>, File<'bytes>)> for Archive<'bytes>

source§

fn from_iter<T>(iter: T) -> Selfwhere + T: IntoIterator<Item = (Key<'bytes>, File<'bytes>)>,

Creates a value from an iterator. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this Archive<'bytes>

§

type Item = <&'this BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this mut Archive<'bytes>

§

type Item = <&'this mut BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this mut BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes> IntoIterator for Archive<'bytes>

§

type Item = <BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl Reader<&File> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: &File) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl Reader<&Path> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: &Path) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Borrowed<'bytes>> for Archive<'bytes>

§

type Error = Error

§

type Item = (Archive<'bytes>, Options)

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Copied<'bytes>> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Archive<'bytes>

§

impl<'bytes> Send for Archive<'bytes>

§

impl<'bytes> Sync for Archive<'bytes>

§

impl<'bytes> Unpin for Archive<'bytes>

§

impl<'bytes> UnwindSafe for Archive<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.ArchiveKey.html b/ba2/fo4/struct.ArchiveKey.html new file mode 100644 index 0000000..7bccdf4 --- /dev/null +++ b/ba2/fo4/struct.ArchiveKey.html @@ -0,0 +1,21 @@ +ArchiveKey in ba2::fo4 - Rust

Struct ba2::fo4::ArchiveKey

source ·
pub struct ArchiveKey<'bytes> { /* private fields */ }
Expand description

A key for indexing into the relevant mapping.

+

Implementations§

source§

impl<'bytes> Key<'bytes>

source

pub fn hash(&self) -> &FileHash

source

pub fn name(&self) -> &BStr

Trait Implementations§

source§

impl<'bytes> Borrow<FileHash> for Key<'bytes>

source§

fn borrow(&self) -> &FileHash

Immutably borrows from an owned value. Read more
source§

impl<'bytes> Clone for Key<'bytes>

source§

fn clone(&self) -> Key<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Key<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Key<'bytes>

source§

fn default() -> Key<'bytes>

Returns the “default value” for a type. Read more
source§

impl From<FileHash> for Key<'static>

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl<T> From<T> for Key<'static>where + T: Into<BString>,

source§

fn from(value: T) -> Self

Converts to this type from the input type.
source§

impl<'bytes> Ord for Key<'bytes>

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'bytes> PartialEq for Key<'bytes>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'bytes> PartialOrd for Key<'bytes>

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'bytes> Eq for Key<'bytes>

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Key<'bytes>

§

impl<'bytes> Send for Key<'bytes>

§

impl<'bytes> Sync for Key<'bytes>

§

impl<'bytes> Unpin for Key<'bytes>

§

impl<'bytes> UnwindSafe for Key<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.ArchiveOptions.html b/ba2/fo4/struct.ArchiveOptions.html new file mode 100644 index 0000000..9d8085f --- /dev/null +++ b/ba2/fo4/struct.ArchiveOptions.html @@ -0,0 +1,43 @@ +ArchiveOptions in ba2::fo4 - Rust

Struct ba2::fo4::ArchiveOptions

source ·
pub struct ArchiveOptions { /* private fields */ }
Expand description

Info about the contents of the given archive.

+ +
use ba2::fo4::{ArchiveOptions, CompressionFormat, Format, Version};
+
+// Write an archive for FO4/FO76, GNRL format
+let _ = ArchiveOptions::builder()
+    .format(Format::GNRL)
+    .version(Version::v1)
+    .compression_format(CompressionFormat::Zip)
+    .build();
+
+// Write an archive for FO4/FO76, DX10 format
+let _ = ArchiveOptions::builder()
+    .format(Format::DX10)
+    .version(Version::v1)
+    .compression_format(CompressionFormat::Zip)
+    .build();
+
+// Write an archive for SF, GNRL format
+let _ = ArchiveOptions::builder()
+    .format(Format::GNRL)
+    .version(Version::v2)
+    .compression_format(CompressionFormat::Zip)
+    .build();
+
+// Write an archive for SF, DX10 format
+let _ = ArchiveOptions::builder()
+    .format(Format::DX10)
+    .version(Version::v3)
+    .compression_format(CompressionFormat::LZ4)
+    .build();
+

Implementations§

Trait Implementations§

source§

impl Clone for Options

source§

fn clone(&self) -> Options

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Options

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Options

source§

fn default() -> Options

Returns the “default value” for a type. Read more
source§

impl From<&Options> for CompressionOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for CompressionOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for ReadOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for ReadOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for WriteOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for WriteOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for WriteOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for WriteOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl Copy for Options

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.ArchiveOptionsBuilder.html b/ba2/fo4/struct.ArchiveOptionsBuilder.html new file mode 100644 index 0000000..0366f0f --- /dev/null +++ b/ba2/fo4/struct.ArchiveOptionsBuilder.html @@ -0,0 +1,13 @@ +ArchiveOptionsBuilder in ba2::fo4 - Rust
pub struct ArchiveOptionsBuilder(/* private fields */);
Expand description

See also ArchiveOptions.

+

Implementations§

source§

impl OptionsBuilder

source

pub fn build(self) -> Options

source

pub fn compression_format(self, compression_format: CompressionFormat) -> Self

source

pub fn format(self, format: Format) -> Self

source

pub fn new() -> Self

source

pub fn strings(self, strings: bool) -> Self

source

pub fn version(self, version: Version) -> Self

Trait Implementations§

source§

impl Clone for OptionsBuilder

source§

fn clone(&self) -> OptionsBuilder

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for OptionsBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for OptionsBuilder

source§

fn default() -> OptionsBuilder

Returns the “default value” for a type. Read more
source§

impl Copy for OptionsBuilder

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.Chunk.html b/ba2/fo4/struct.Chunk.html new file mode 100644 index 0000000..dafe8c8 --- /dev/null +++ b/ba2/fo4/struct.Chunk.html @@ -0,0 +1,30 @@ +Chunk in ba2::fo4 - Rust

Struct ba2::fo4::Chunk

source ·
pub struct Chunk<'bytes> {
+    pub mips: Option<RangeInclusive<u16>>,
+    /* private fields */
+}
Expand description

Represents a chunk of a file within the FO4 virtual filesystem.

+

Fields§

§mips: Option<RangeInclusive<u16>>

Implementations§

source§

impl<'bytes> Chunk<'bytes>

source

pub fn as_bytes(&self) -> &[u8]

source

pub fn as_ptr(&self) -> *const u8

source

pub fn into_owned(self) -> Chunk<'static>

source

pub fn is_empty(&self) -> bool

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source§

impl<'bytes> Chunk<'bytes>

source

pub fn compress(&self, options: &CompressionOptions) -> Result<Chunk<'static>>

source

pub fn decompress(&self, options: &CompressionOptions) -> Result<Chunk<'static>>

source

pub fn decompressed_len(&self) -> Option<usize>

source

pub fn is_compressed(&self) -> bool

source

pub fn is_decompressed(&self) -> bool

source

pub fn write<Out>( + &self, + stream: &mut Out, + options: &CompressionOptions +) -> Result<()>where + Out: ?Sized + Write,

source§

impl<'bytes> Chunk<'bytes>

source

pub fn compress_into( + &self, + out: &mut Vec<u8>, + options: &CompressionOptions +) -> Result<()>

source

pub fn decompress_into( + &self, + out: &mut Vec<u8>, + options: &CompressionOptions +) -> Result<()>

Trait Implementations§

source§

impl<'bytes> Clone for Chunk<'bytes>

source§

fn clone(&self) -> Chunk<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> CompressableFrom<&'bytes [u8]> for Chunk<'bytes>

source§

fn from_compressed(value: &'bytes [u8], decompressed_len: usize) -> Self

Makes a compressed instance of Self using the given data.
source§

fn from_decompressed(value: &'bytes [u8]) -> Self

Makes a decompressed instance of Self using the given data.
source§

impl<'bytes, const N: usize> CompressableFrom<&'bytes [u8; N]> for Chunk<'bytes>

source§

fn from_compressed(value: &'bytes [u8; N], decompressed_len: usize) -> Self

Makes a compressed instance of Self using the given data.
source§

fn from_decompressed(value: &'bytes [u8; N]) -> Self

Makes a decompressed instance of Self using the given data.
source§

impl CompressableFrom<Box<[u8]>> for Chunk<'static>

source§

fn from_compressed(value: Box<[u8]>, decompressed_len: usize) -> Self

Makes a compressed instance of Self using the given data.
source§

fn from_decompressed(value: Box<[u8]>) -> Self

Makes a decompressed instance of Self using the given data.
source§

impl<'bytes> Debug for Chunk<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Chunk<'bytes>

source§

fn default() -> Chunk<'bytes>

Returns the “default value” for a type. Read more
source§

impl<'bytes> FromIterator<Chunk<'bytes>> for File<'bytes>

source§

fn from_iter<T>(iter: T) -> Selfwhere + T: IntoIterator<Item = Chunk<'bytes>>,

Creates a value from an iterator. Read more

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Chunk<'bytes>

§

impl<'bytes> Send for Chunk<'bytes>

§

impl<'bytes> Sync for Chunk<'bytes>

§

impl<'bytes> Unpin for Chunk<'bytes>

§

impl<'bytes> UnwindSafe for Chunk<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.ChunkCompressionOptions.html b/ba2/fo4/struct.ChunkCompressionOptions.html new file mode 100644 index 0000000..86dfea8 --- /dev/null +++ b/ba2/fo4/struct.ChunkCompressionOptions.html @@ -0,0 +1,38 @@ +ChunkCompressionOptions in ba2::fo4 - Rust
pub struct ChunkCompressionOptions { /* private fields */ }
Expand description

Common parameters to configure how chunks are compressed.

+ +
use ba2::fo4::{ChunkCompressionOptions, CompressionFormat, CompressionLevel};
+
+// Configure for FO4/FO76
+let _ = ChunkCompressionOptions::builder()
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::FO4)
+    .build();
+
+// Configure for FO4 on the xbox
+let _ = ChunkCompressionOptions::builder()
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::FO4Xbox)
+    .build();
+
+// Configure for SF, GNRL format
+let _ = ChunkCompressionOptions::builder()
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::SF)
+    .build();
+
+// Configure for SF, DX10 format
+let _ = ChunkCompressionOptions::builder()
+    .compression_format(CompressionFormat::LZ4)
+    .build();
+

Implementations§

Trait Implementations§

source§

impl Clone for CompressionOptions

source§

fn clone(&self) -> CompressionOptions

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CompressionOptions

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionOptions

source§

fn default() -> CompressionOptions

Returns the “default value” for a type. Read more
source§

impl From<&Options> for CompressionOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl Copy for CompressionOptions

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.ChunkCompressionOptionsBuilder.html b/ba2/fo4/struct.ChunkCompressionOptionsBuilder.html new file mode 100644 index 0000000..5033e9c --- /dev/null +++ b/ba2/fo4/struct.ChunkCompressionOptionsBuilder.html @@ -0,0 +1,12 @@ +ChunkCompressionOptionsBuilder in ba2::fo4 - Rust
pub struct ChunkCompressionOptionsBuilder(/* private fields */);
Expand description

Implementations§

source§

impl CompressionOptionsBuilder

source

pub fn build(self) -> CompressionOptions

source

pub fn compression_format(self, compression_format: CompressionFormat) -> Self

source

pub fn compression_level(self, compression_level: CompressionLevel) -> Self

source

pub fn new() -> Self

Trait Implementations§

source§

impl Debug for CompressionOptionsBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionOptionsBuilder

source§

fn default() -> CompressionOptionsBuilder

Returns the “default value” for a type. Read more
source§

impl From<&Options> for CompressionOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.DX10Header.html b/ba2/fo4/struct.DX10Header.html new file mode 100644 index 0000000..420749a --- /dev/null +++ b/ba2/fo4/struct.DX10Header.html @@ -0,0 +1,22 @@ +DX10Header in ba2::fo4 - Rust

Struct ba2::fo4::DX10Header

source ·
pub struct DX10Header {
+    pub height: u16,
+    pub width: u16,
+    pub mip_count: u8,
+    pub format: u8,
+    pub flags: u8,
+    pub tile_mode: u8,
+}
Expand description

File header for DX10 archives.

+

Fields§

§height: u16§width: u16§mip_count: u8§format: u8§flags: u8§tile_mode: u8

Trait Implementations§

source§

impl Clone for DX10

source§

fn clone(&self) -> DX10

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for DX10

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for DX10

source§

fn default() -> DX10

Returns the “default value” for a type. Read more
source§

impl From<DX10> for Header

source§

fn from(value: DX10) -> Self

Converts to this type from the input type.
source§

impl PartialEq for DX10

source§

fn eq(&self, other: &DX10) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for DX10

source§

impl Eq for DX10

source§

impl StructuralEq for DX10

source§

impl StructuralPartialEq for DX10

Auto Trait Implementations§

§

impl RefUnwindSafe for DX10

§

impl Send for DX10

§

impl Sync for DX10

§

impl Unpin for DX10

§

impl UnwindSafe for DX10

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.File.html b/ba2/fo4/struct.File.html new file mode 100644 index 0000000..4558e8c --- /dev/null +++ b/ba2/fo4/struct.File.html @@ -0,0 +1,41 @@ +File in ba2::fo4 - Rust

Struct ba2::fo4::File

source ·
pub struct File<'bytes> {
+    pub header: Header,
+    /* private fields */
+}
Expand description

Represents a file within the FO4 virtual filesystem.

+

Fields§

§header: Header

Implementations§

source§

impl<'bytes> File<'bytes>

source

pub fn as_mut_ptr(&mut self) -> *mut Chunk<'bytes>

source

pub fn as_mut_slice(&mut self) -> &mut [Chunk<'bytes>]

source

pub fn as_ptr(&self) -> *const Chunk<'bytes>

source

pub fn as_slice(&self) -> &[Chunk<'bytes>]

source

pub fn clear(&mut self)

source

pub fn drain<R>(&mut self, range: R) -> impl Iterator<Item = Chunk<'bytes>> + '_where + R: RangeBounds<usize>,

Panics
+

Panics if start_bound exceeds end_bound, or if end_bound exceeds len.

+
source

pub fn insert(&mut self, index: usize, element: Chunk<'bytes>)

Panics
+

Panics if index exceeds len, or is_full.

+
source

pub fn is_empty(&self) -> bool

source

pub fn is_full(&self) -> bool

source

pub fn iter(&self) -> impl Iterator<Item = &Chunk<'bytes>>

source

pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Chunk<'bytes>>

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source

pub fn pop(&mut self) -> Option<Chunk<'bytes>>

source

pub fn push(&mut self, element: Chunk<'bytes>)

Panics
+

Panics if is_full.

+
source

pub fn remaining_capacity(&self) -> usize

source

pub fn remove(&mut self, index: usize) -> Chunk<'bytes>

Panics
+

Panics if index exceeds len.

+
source

pub fn retain_mut<F>(&mut self, f: F)where + F: FnMut(&mut Chunk<'bytes>) -> bool,

source

pub fn swap_remove(&mut self, index: usize) -> Chunk<'bytes>

Panics
+

Panics if index exceeds len, or is_empty.

+
source

pub fn truncate(&mut self, len: usize)

source

pub fn try_insert( + &mut self, + index: usize, + element: Chunk<'bytes> +) -> Result<(), CapacityError<'bytes>>

Panics
+

Panics if index exceeds len.

+
source

pub fn try_push( + &mut self, + element: Chunk<'bytes> +) -> Result<(), CapacityError<'bytes>>

source

pub fn try_swap_remove(&mut self, index: usize) -> Option<Chunk<'bytes>>

Panics
+

Panics if index exceeds len.

+
source

pub fn write<Out>(&self, stream: &mut Out, options: &WriteOptions) -> Result<()>where + Out: ?Sized + Write,

Trait Implementations§

source§

impl<'bytes> Clone for File<'bytes>

source§

fn clone(&self) -> File<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for File<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for File<'bytes>

source§

fn default() -> File<'bytes>

Returns the “default value” for a type. Read more
source§

impl<'bytes> FromIterator<Chunk<'bytes>> for File<'bytes>

source§

fn from_iter<T>(iter: T) -> Selfwhere + T: IntoIterator<Item = Chunk<'bytes>>,

Creates a value from an iterator. Read more
source§

impl<'bytes> Index<usize> for File<'bytes>

§

type Output = Chunk<'bytes>

The returned type after indexing.
source§

fn index(&self, index: usize) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
source§

impl<'bytes> IndexMut<usize> for File<'bytes>

source§

fn index_mut(&mut self, index: usize) -> &mut Self::Output

Performs the mutable indexing (container[index]) operation. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this File<'bytes>

§

type Item = <&'this Vec<Chunk<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this Vec<Chunk<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this mut File<'bytes>

§

type Item = <&'this mut Vec<Chunk<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this mut Vec<Chunk<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes> IntoIterator for File<'bytes>

§

type Item = <Vec<Chunk<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <Vec<Chunk<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl ReaderWithOptions<&File> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: &File, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl ReaderWithOptions<&Path> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: &Path, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl<'bytes> ReaderWithOptions<Borrowed<'bytes>> for File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

§

type Options = ReadOptions

source§

fn read(source: Borrowed<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl<'bytes> ReaderWithOptions<Copied<'bytes>> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: Copied<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for File<'bytes>

§

impl<'bytes> Send for File<'bytes>

§

impl<'bytes> Sync for File<'bytes>

§

impl<'bytes> Unpin for File<'bytes>

§

impl<'bytes> UnwindSafe for File<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.FileCapacityError.html b/ba2/fo4/struct.FileCapacityError.html new file mode 100644 index 0000000..5a06a87 --- /dev/null +++ b/ba2/fo4/struct.FileCapacityError.html @@ -0,0 +1,13 @@ +FileCapacityError in ba2::fo4 - Rust

Struct ba2::fo4::FileCapacityError

source ·
pub struct FileCapacityError<'bytes>(/* private fields */);
Expand description

File is at chunk capacity.

+

Implementations§

source§

impl<'bytes> CapacityError<'bytes>

source

pub fn into_element(self) -> Chunk<'bytes>

Trait Implementations§

source§

impl<'bytes> Debug for CapacityError<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Display for CapacityError<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Error for CapacityError<'bytes>

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for CapacityError<'bytes>

§

impl<'bytes> Send for CapacityError<'bytes>

§

impl<'bytes> Sync for CapacityError<'bytes>

§

impl<'bytes> Unpin for CapacityError<'bytes>

§

impl<'bytes> UnwindSafe for CapacityError<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.FileHash.html b/ba2/fo4/struct.FileHash.html new file mode 100644 index 0000000..6cec61e --- /dev/null +++ b/ba2/fo4/struct.FileHash.html @@ -0,0 +1,28 @@ +FileHash in ba2::fo4 - Rust

Struct ba2::fo4::FileHash

source ·
pub struct FileHash(/* private fields */);
Expand description

See also Hash.

+

Implementations§

source§

impl FileHash

source

pub fn new() -> Self

Trait Implementations§

source§

impl AsMut<Hash> for FileHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for FileHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<'bytes> Borrow<FileHash> for Key<'bytes>

source§

fn borrow(&self) -> &FileHash

Immutably borrows from an owned value. Read more
source§

impl Borrow<Hash> for FileHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for FileHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl Clone for FileHash

source§

fn clone(&self) -> FileHash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for FileHash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for FileHash

source§

fn default() -> FileHash

Returns the “default value” for a type. Read more
source§

impl Deref for FileHash

§

type Target = Hash

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for FileHash

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl From<FileHash> for Hash

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<FileHash> for Key<'static>

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for FileHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl Ord for FileHash

source§

fn cmp(&self, other: &FileHash) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<FileHash> for Hash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for FileHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for FileHash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<FileHash> for Hash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for FileHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for FileHash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for FileHash

source§

impl Eq for FileHash

source§

impl StructuralEq for FileHash

source§

impl StructuralPartialEq for FileHash

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.FileReadOptions.html b/ba2/fo4/struct.FileReadOptions.html new file mode 100644 index 0000000..8641a69 --- /dev/null +++ b/ba2/fo4/struct.FileReadOptions.html @@ -0,0 +1,65 @@ +FileReadOptions in ba2::fo4 - Rust

Struct ba2::fo4::FileReadOptions

source ·
pub struct FileReadOptions { /* private fields */ }
Expand description

Common parameters to configure how files are read.

+ +
use ba2::{
+    fo4::{CompressionFormat, CompressionLevel, FileReadOptions, Format},
+    CompressionResult,
+};
+
+// Read and compress a file for FO4/FO76, GNRL format
+let _ = FileReadOptions::builder()
+    .format(Format::GNRL)
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::FO4)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+
+// Read and compress a file for FO4/FO76, DX10 format
+let _ = FileReadOptions::builder()
+    .format(Format::DX10)
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::FO4)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+
+// Read and compress a file for FO4 on the xbox, GNRL format
+let _ = FileReadOptions::builder()
+    .format(Format::GNRL)
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::FO4Xbox)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+
+// Read and compress a file for FO4 on the xbox, DX10 format
+let _ = FileReadOptions::builder()
+    .format(Format::DX10)
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::FO4Xbox)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+
+// Read and compress a file for SF, GNRL format
+let _ = FileReadOptions::builder()
+    .format(Format::GNRL)
+    .compression_format(CompressionFormat::Zip)
+    .compression_level(CompressionLevel::SF)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+
+// Read and compress a file for SF, DX10 format
+let _ = FileReadOptions::builder()
+    .format(Format::DX10)
+    .compression_format(CompressionFormat::LZ4)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+

Implementations§

Trait Implementations§

source§

impl Clone for ReadOptions

source§

fn clone(&self) -> ReadOptions

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ReadOptions

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ReadOptions

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl From<&Options> for ReadOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl Copy for ReadOptions

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.FileReadOptionsBuilder.html b/ba2/fo4/struct.FileReadOptionsBuilder.html new file mode 100644 index 0000000..38ca4d9 --- /dev/null +++ b/ba2/fo4/struct.FileReadOptionsBuilder.html @@ -0,0 +1,12 @@ +FileReadOptionsBuilder in ba2::fo4 - Rust
pub struct FileReadOptionsBuilder(/* private fields */);
Expand description

See also FileReadOptions.

+

Implementations§

source§

impl ReadOptionsBuilder

source

pub fn build(self) -> ReadOptions

source

pub fn compression_format(self, compression_format: CompressionFormat) -> Self

source

pub fn compression_level(self, compression_level: CompressionLevel) -> Self

source

pub fn compression_result(self, compression_result: CompressionResult) -> Self

source

pub fn format(self, format: Format) -> Self

source

pub fn mip_chunk_height(self, mip_chunk_height: usize) -> Self

source

pub fn mip_chunk_width(self, mip_chunk_width: usize) -> Self

source

pub fn new() -> Self

Trait Implementations§

source§

impl Debug for ReadOptionsBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ReadOptionsBuilder

source§

fn default() -> ReadOptionsBuilder

Returns the “default value” for a type. Read more
source§

impl From<&Options> for ReadOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.FileWriteOptions.html b/ba2/fo4/struct.FileWriteOptions.html new file mode 100644 index 0000000..6c29839 --- /dev/null +++ b/ba2/fo4/struct.FileWriteOptions.html @@ -0,0 +1,30 @@ +FileWriteOptions in ba2::fo4 - Rust

Struct ba2::fo4::FileWriteOptions

source ·
pub struct FileWriteOptions { /* private fields */ }
Expand description

Common parameters to configure how files are written.

+ +
use ba2::fo4::{CompressionFormat, FileWriteOptions, Format};
+
+// Write a file for FO4/FO76
+let _ = FileWriteOptions::builder()
+    .compression_format(CompressionFormat::Zip)
+    .build();
+
+// Write a file for SF, GNRL format
+let _ = FileWriteOptions::builder()
+    .compression_format(CompressionFormat::Zip)
+    .build();
+
+// Write a file for SF, DX10 format
+let _ = FileWriteOptions::builder()
+    .compression_format(CompressionFormat::LZ4)
+    .build();
+

Implementations§

Trait Implementations§

source§

impl Clone for WriteOptions

source§

fn clone(&self) -> WriteOptions

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for WriteOptions

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for WriteOptions

source§

fn default() -> WriteOptions

Returns the “default value” for a type. Read more
source§

impl From<&Options> for WriteOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for WriteOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl Copy for WriteOptions

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.FileWriteOptionsBuilder.html b/ba2/fo4/struct.FileWriteOptionsBuilder.html new file mode 100644 index 0000000..58bb6c8 --- /dev/null +++ b/ba2/fo4/struct.FileWriteOptionsBuilder.html @@ -0,0 +1,12 @@ +FileWriteOptionsBuilder in ba2::fo4 - Rust
pub struct FileWriteOptionsBuilder(/* private fields */);
Expand description

See also FileWriteOptions.

+

Implementations§

source§

impl WriteOptionsBuilder

source

pub fn build(self) -> WriteOptions

source

pub fn compression_format(self, compression_format: CompressionFormat) -> Self

source

pub fn new() -> Self

Trait Implementations§

source§

impl Debug for WriteOptionsBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for WriteOptionsBuilder

source§

fn default() -> WriteOptionsBuilder

Returns the “default value” for a type. Read more
source§

impl From<&Options> for WriteOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for WriteOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.GNMFHeader.html b/ba2/fo4/struct.GNMFHeader.html new file mode 100644 index 0000000..129e5bb --- /dev/null +++ b/ba2/fo4/struct.GNMFHeader.html @@ -0,0 +1,18 @@ +GNMFHeader in ba2::fo4 - Rust

Struct ba2::fo4::GNMFHeader

source ·
pub struct GNMFHeader {
+    pub metadata: [u32; 8],
+}
Expand description

File header for GNMF archives.

+

Fields§

§metadata: [u32; 8]

See here for more info.

+

Trait Implementations§

source§

impl Clone for GNMF

source§

fn clone(&self) -> GNMF

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for GNMF

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for GNMF

source§

fn default() -> GNMF

Returns the “default value” for a type. Read more
source§

impl From<GNMF> for Header

source§

fn from(value: GNMF) -> Self

Converts to this type from the input type.
source§

impl PartialEq for GNMF

source§

fn eq(&self, other: &GNMF) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for GNMF

source§

impl Eq for GNMF

source§

impl StructuralEq for GNMF

source§

impl StructuralPartialEq for GNMF

Auto Trait Implementations§

§

impl RefUnwindSafe for GNMF

§

impl Send for GNMF

§

impl Sync for GNMF

§

impl Unpin for GNMF

§

impl UnwindSafe for GNMF

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/struct.Hash.html b/ba2/fo4/struct.Hash.html new file mode 100644 index 0000000..1bd03f7 --- /dev/null +++ b/ba2/fo4/struct.Hash.html @@ -0,0 +1,35 @@ +Hash in ba2::fo4 - Rust

Struct ba2::fo4::Hash

source ·
#[repr(C)]
pub struct Hash { + pub file: u32, + pub extension: u32, + pub directory: u32, +}
Expand description

The underlying hash object used to uniquely identify objects within the archive.

+

Fields§

§file: u32

The file’s stem crc.

+
§extension: u32

The first 4 bytes of the file’s extension.

+
§directory: u32

The file’s parent path crc.

+

Implementations§

source§

impl Hash

source

pub fn new() -> Self

Trait Implementations§

source§

impl AsMut<Hash> for FileHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for FileHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Borrow<Hash> for FileHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for FileHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl Clone for Hash

source§

fn clone(&self) -> Hash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Hash

source§

fn default() -> Hash

Returns the “default value” for a type. Read more
source§

impl From<FileHash> for Hash

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for FileHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl Ord for Hash

source§

fn cmp(&self, other: &Hash) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<FileHash> for Hash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for FileHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Hash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<FileHash> for Hash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for FileHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for Hash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Hash

source§

impl Eq for Hash

source§

impl StructuralEq for Hash

source§

impl StructuralPartialEq for Hash

Auto Trait Implementations§

§

impl RefUnwindSafe for Hash

§

impl Send for Hash

§

impl Sync for Hash

§

impl Unpin for Hash

§

impl UnwindSafe for Hash

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/fo4/type.Result.html b/ba2/fo4/type.Result.html new file mode 100644 index 0000000..8a9154d --- /dev/null +++ b/ba2/fo4/type.Result.html @@ -0,0 +1,6 @@ +Result in ba2::fo4 - Rust

Type Alias ba2::fo4::Result

source ·
pub type Result<T> = Result<T, Error>;

Aliased Type§

enum Result<T> {
+    Ok(T),
+    Err(Error),
+}

Variants§

§1.0.0

Ok(T)

Contains the success value

+
§1.0.0

Err(Error)

Contains the error value

+
\ No newline at end of file diff --git a/ba2/guess/enum.FileFormat.html b/ba2/guess/enum.FileFormat.html new file mode 100644 index 0000000..c0ad916 --- /dev/null +++ b/ba2/guess/enum.FileFormat.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../ba2/enum.FileFormat.html...

+ + + \ No newline at end of file diff --git a/ba2/guess/fn.guess_format.html b/ba2/guess/fn.guess_format.html new file mode 100644 index 0000000..d598212 --- /dev/null +++ b/ba2/guess/fn.guess_format.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../ba2/fn.guess_format.html...

+ + + \ No newline at end of file diff --git a/ba2/index.html b/ba2/index.html new file mode 100644 index 0000000..4eb28be --- /dev/null +++ b/ba2/index.html @@ -0,0 +1,7 @@ +ba2 - Rust

Crate ba2

source ·
Expand description

Archives come in various flavors, and the specific variant you’ll need to use depends on which game you’re working with. Learn more by choosing one of tes3, tes4, or fo4.

+

If you are uncertain of the origins of your archive, then you may use guess_format to find a starting point.

+

A note on strings

+

The Creation Engine absolutely does not handle unicode correctly, and even has some nasty, extant bugs which exist related to characters that utilize the extended ascii range. As such, all strings are marked as binary strings, without encoding (see also BStr or BString). If you must re-encode strings, then, generally speaking, they are encoded using the system code page of whatever computer happened to write the archive. That means English copies of the game are encoded using Windows-1252, Russian copies using Windows-1251, etc. However, this is not a guarantee and is the source of much consternation when writing internationalized applications for the Creation Engine games.

+

Modules

  • Fallout 4
  • Convenience using statements for traits that are needed to work with the library.
  • TES III: Morrowind
  • TES IV: Oblivion

Structs

  • A wrapper for &[u8] that provides convenient string oriented trait impls.
  • A wrapper for Vec<u8> that provides convenient string oriented trait +impls.
  • Makes a shallow copy of the input.
  • Makes a deep copy of the input.

Enums

  • Indicates whether the operation should finish by compressing the data or not.
  • The file format for a given archive.

Traits

  • A trait that extends &[u8] with string oriented methods.
  • A trait that extends Vec<u8> with string oriented methods.
  • A trait that creates an optionally compressed container using the given value.
  • A trait that enables reading from various sources.
  • A trait that enables reading from various sources, with configuration options.

Functions

\ No newline at end of file diff --git a/ba2/prelude/index.html b/ba2/prelude/index.html new file mode 100644 index 0000000..569ca48 --- /dev/null +++ b/ba2/prelude/index.html @@ -0,0 +1,2 @@ +ba2::prelude - Rust

Module ba2::prelude

source ·
Expand description

Convenience using statements for traits that are needed to work with the library.

+

Re-exports

\ No newline at end of file diff --git a/ba2/prelude/sidebar-items.js b/ba2/prelude/sidebar-items.js new file mode 100644 index 0000000..5244ce0 --- /dev/null +++ b/ba2/prelude/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {}; \ No newline at end of file diff --git a/ba2/sidebar-items.js b/ba2/sidebar-items.js new file mode 100644 index 0000000..98923f3 --- /dev/null +++ b/ba2/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CompressionResult","FileFormat"],"fn":["guess_format"],"mod":["fo4","prelude","tes3","tes4"],"struct":["BStr","BString","Borrowed","Copied"],"trait":["ByteSlice","ByteVec","CompressableFrom","Reader","ReaderWithOptions"]}; \ No newline at end of file diff --git a/ba2/struct.BStr.html b/ba2/struct.BStr.html new file mode 100644 index 0000000..f275c77 --- /dev/null +++ b/ba2/struct.BStr.html @@ -0,0 +1,2501 @@ +BStr in ba2 - Rust

Struct ba2::BStr

pub struct BStr { /* private fields */ }
Expand description

A wrapper for &[u8] that provides convenient string oriented trait impls.

+

If you need ownership or a growable byte string buffer, then use +BString.

+

Using a &BStr is just like using a &[u8], since BStr +implements Deref to [u8]. So all methods available on [u8] +are also available on BStr.

+

Representation

+

A &BStr has the same representation as a &str. That is, a &BStr is +a fat pointer which consists of a pointer to some bytes and a length.

+

Trait implementations

+

The BStr type has a number of trait implementations, and in particular, +defines equality and ordinal comparisons between &BStr, &str and +&[u8] for convenience.

+

The Debug implementation for BStr shows its bytes as a normal string. +For invalid UTF-8, hex escape sequences are used.

+

The Display implementation behaves as if BStr were first lossily +converted to a str. Invalid UTF-8 bytes are substituted with the Unicode +replacement codepoint, which looks like this: �.

+

Implementations§

§

impl BStr

pub fn new<B, 'a>(bytes: &'a B) -> &'a BStrwhere + B: AsRef<[u8]> + ?Sized,

Directly creates a BStr slice from anything that can be converted +to a byte slice.

+

This is very similar to the B function, except this +returns a &BStr instead of a &[u8].

+

This is a cost-free conversion.

+
Example
+

You can create BStr’s from byte arrays, byte slices or even string +slices:

+ +
use bstr::BStr;
+
+let a = BStr::new(b"abc");
+let b = BStr::new(&b"abc"[..]);
+let c = BStr::new("abc");
+
+assert_eq!(a, b);
+assert_eq!(a, c);
+

Methods from Deref<Target = [u8]>§

source

pub fn flatten(&self) -> &[T]

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

Takes a &[[T; N]], and flattens it to a &[T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].flatten(),
+    [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+
source

pub fn flatten_mut(&mut self) -> &mut [T]

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

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.flatten_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the last item in the slice.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

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

Returns the first N elements of the slice, or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

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

Returns a mutable reference to the first N elements of the slice, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

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

Returns the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

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

Returns a mutable reference to the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

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

Returns the last N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk::<2>() {
+    assert_eq!(last, &[1, 2]);
+    assert_eq!(elements, &[0]);
+}
+
source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

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

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

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

Returns the last element of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

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

Returns a mutable pointer to the last item in the slice.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Panics
+

Panics if a or b are out of bounds.

+
Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

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

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
Panics
+

Panics if size is 0.

+
Examples
+
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

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

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

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

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

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

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

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

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

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

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

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

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

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

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

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

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

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

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
source

pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>where + F: FnMut(&T, &T) -> bool,

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

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
source

pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>where + F: FnMut(&T, &T) -> bool,

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

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

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

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

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

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])

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

Divides one slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.split_array_ref::<0>();
+   assert_eq!(left, &[]);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<2>();
+    assert_eq!(left, &[1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<6>();
+    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T])

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

Divides one mutable slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.split_array_mut::<2>();
+assert_eq!(left, &mut [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])

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

Divides one slice into an array and a remainder slice at an index from +the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index len - N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.rsplit_array_ref::<0>();
+   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+   assert_eq!(right, &[]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<2>();
+    assert_eq!(left, [1, 2, 3, 4]);
+    assert_eq!(right, &[5, 6]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<6>();
+    assert_eq!(left, []);
+    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
+
source

pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N])

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

Divides one mutable slice into an array and a remainder slice at an +index from the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.rsplit_array_mut::<4>();
+assert_eq!(left, [1, 0]);
+assert_eq!(right, &mut [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>where + F: FnMut(&T) -> bool,

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

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are resent in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>where + F: FnMut(&T) -> bool,

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

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are resent in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> boolwhere + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> boolwhere + T: PartialEq,

Returns true if needle is a prefix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> boolwhere + T: PartialEq,

Returns true if needle is a suffix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice.

+

If the slice does not start with prefix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice.

+

If the slice does not end with suffix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])where + T: Ord,

Reorder the slice such that the element at index is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median
+v.select_nth_unstable(2);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median as if the slice were sorted in descending order.
+v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Return the median as if the array were sorted according to absolute value.
+v.select_nth_unstable_by_key(2, |a| a.abs());
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])where + T: PartialEq,

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

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T, &mut T) -> bool,

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

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T) -> K, + K: PartialEq,

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

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)where + T: Clone,

Fills self with elements by cloning value.

+
Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

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

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
Examples
+
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    use std::simd::f32x4;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

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

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> boolwhere + T: PartialOrd,

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

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> boolwhere + F: FnMut(&'a T, &'a T) -> Option<Ordering>,

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

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine the ordering of two elements. Apart from that, it’s equivalent to +is_sorted; see its documentation for more information.

+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> boolwhere + F: FnMut(&'a T) -> K, + K: PartialOrd,

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

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usizewhere + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<R, 'a>(self: &mut &'a [T], range: R) -> Option<&'a [T]>where + R: OneSidedRange<usize>,

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

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<R, 'a>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>where + R: OneSidedRange<usize>,

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

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

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

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

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

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

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

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

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

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

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

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

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

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

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

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

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

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
source

pub fn trim_ascii_start(&self) -> &[u8]

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

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
source

pub fn trim_ascii_end(&self) -> &[u8]

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

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
source

pub fn trim_ascii(&self) -> &[u8]

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

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn as_str(&self) -> &str

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

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

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

Views this slice of ASCII characters as a slice of u8 bytes.

+
source

pub fn sort_floats(&mut self)

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

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn sort_floats(&mut self)

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

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn sort(&mut self)where + T: Ord,

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>where + T: Clone,

Copies self into a new Vec.

+
Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>where + A: Allocator, + T: Clone,

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

Copies self into a new Vec with an allocator.

+
Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>where + T: Copy,

Creates a vector by copying a slice n times.

+
Panics
+

This function will panic if the capacity would overflow.

+
Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

§

impl AsMut<[u8]> for BStr

§

fn as_mut(&mut self) -> &mut [u8]

Converts this type into a mutable reference of the (usually inferred) input type.
§

impl AsMut<BStr> for [u8]

§

fn as_mut(&mut self) -> &mut BStr

Converts this type into a mutable reference of the (usually inferred) input type.
§

impl AsMut<BStr> for BString

§

fn as_mut(&mut self) -> &mut BStr

Converts this type into a mutable reference of the (usually inferred) input type.
§

impl AsRef<[u8]> for BStr

§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
§

impl AsRef<BStr> for [u8]

§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
§

impl AsRef<BStr> for BStr

§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
§

impl AsRef<BStr> for BString

§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
§

impl AsRef<BStr> for str

§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
§

impl Borrow<[u8]> for BStr

§

fn borrow(&self) -> &[u8]

Immutably borrows from an owned value. Read more
§

impl Borrow<BStr> for [u8]

§

fn borrow(&self) -> &BStr

Immutably borrows from an owned value. Read more
§

impl Borrow<BStr> for BString

§

fn borrow(&self) -> &BStr

Immutably borrows from an owned value. Read more
§

impl Borrow<BStr> for Vec<u8>

§

fn borrow(&self) -> &BStr

Immutably borrows from an owned value. Read more
§

impl Borrow<BStr> for str

§

fn borrow(&self) -> &BStr

Immutably borrows from an owned value. Read more
§

impl BorrowMut<[u8]> for BStr

§

fn borrow_mut(&mut self) -> &mut [u8]

Mutably borrows from an owned value. Read more
§

impl BorrowMut<BStr> for [u8]

§

fn borrow_mut(&mut self) -> &mut BStr

Mutably borrows from an owned value. Read more
§

impl BorrowMut<BStr> for BString

§

fn borrow_mut(&mut self) -> &mut BStr

Mutably borrows from an owned value. Read more
§

impl BorrowMut<BStr> for Vec<u8>

§

fn borrow_mut(&mut self) -> &mut BStr

Mutably borrows from an owned value. Read more
§

impl Debug for BStr

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<'a> Default for &'a BStr

§

fn default() -> &'a BStr

Returns the “default value” for a type. Read more
§

impl<'a> Default for &'a mut BStr

§

fn default() -> &'a mut BStr

Returns the “default value” for a type. Read more
§

impl Deref for BStr

§

type Target = [u8]

The resulting type after dereferencing.
§

fn deref(&self) -> &[u8]

Dereferences the value.
§

impl DerefMut for BStr

§

fn deref_mut(&mut self) -> &mut [u8]

Mutably dereferences the value.
§

impl Display for BStr

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<'a> From<&'a [u8]> for &'a BStr

§

fn from(s: &'a [u8]) -> &'a BStr

Converts to this type from the input type.
§

impl<'a, const N: usize> From<&'a [u8; N]> for &'a BStr

§

fn from(s: &'a [u8; N]) -> &'a BStr

Converts to this type from the input type.
§

impl<'a> From<&'a BStr> for &'a [u8]

§

fn from(s: &'a BStr) -> &'a [u8]

Converts to this type from the input type.
§

impl<'a> From<&'a BStr> for BString

§

fn from(s: &'a BStr) -> BString

Converts to this type from the input type.
§

impl<'a> From<&'a str> for &'a BStr

§

fn from(s: &'a str) -> &'a BStr

Converts to this type from the input type.
§

impl<'a> FromIterator<&'a BStr> for BString

§

fn from_iter<T>(iter: T) -> BStringwhere + T: IntoIterator<Item = &'a BStr>,

Creates a value from an iterator. Read more
§

impl Hash for BStr

§

fn hash<__H>(&self, state: &mut __H)where + __H: Hasher,

Feeds this value into the given Hasher. Read more
§

impl Index<Range<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
§

fn index(&self, r: Range<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
§

impl Index<RangeFrom<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
§

fn index(&self, r: RangeFrom<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
§

impl Index<RangeFull> for BStr

§

type Output = BStr

The returned type after indexing.
§

fn index(&self, _: RangeFull) -> &BStr

Performs the indexing (container[index]) operation. Read more
§

impl Index<RangeInclusive<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
§

fn index(&self, r: RangeInclusive<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
§

impl Index<RangeTo<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
§

fn index(&self, r: RangeTo<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
§

impl Index<RangeToInclusive<usize>> for BStr

§

type Output = BStr

The returned type after indexing.
§

fn index(&self, r: RangeToInclusive<usize>) -> &BStr

Performs the indexing (container[index]) operation. Read more
§

impl Index<usize> for BStr

§

type Output = u8

The returned type after indexing.
§

fn index(&self, idx: usize) -> &u8

Performs the indexing (container[index]) operation. Read more
§

impl IndexMut<Range<usize>> for BStr

§

fn index_mut(&mut self, r: Range<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
§

impl IndexMut<RangeFrom<usize>> for BStr

§

fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
§

impl IndexMut<RangeFull> for BStr

§

fn index_mut(&mut self, _: RangeFull) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
§

impl IndexMut<RangeInclusive<usize>> for BStr

§

fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
§

impl IndexMut<RangeTo<usize>> for BStr

§

fn index_mut(&mut self, r: RangeTo<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
§

impl IndexMut<RangeToInclusive<usize>> for BStr

§

fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut BStr

Performs the mutable indexing (container[index]) operation. Read more
§

impl IndexMut<usize> for BStr

§

fn index_mut(&mut self, idx: usize) -> &mut u8

Performs the mutable indexing (container[index]) operation. Read more
§

impl Ord for BStr

§

fn cmp(&self, other: &BStr) -> Ordering

This method returns an Ordering between self and other. Read more
§

impl<'a, 'b> PartialEq<&'a [u8]> for BStr

§

fn eq(&self, other: &&'a [u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<&'a BStr> for BString

§

fn eq(&self, other: &&'a BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<&'a BStr> for Vec<u8>

§

fn eq(&self, other: &&'a BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<&'a str> for BStr

§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<[u8]> for BStr

§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BStr> for &'a [u8]

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BStr> for &'a str

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BStr> for [u8]

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BStr> for BString

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BStr> for Vec<u8>

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BStr> for str

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for &'a BStr

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for BStr

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<Cow<'a, [u8]>> for &'a BStr

§

fn eq(&self, other: &Cow<'a, [u8]>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<Cow<'a, BStr>> for &'a BStr

§

fn eq(&self, other: &Cow<'a, BStr>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<Cow<'a, str>> for &'a BStr

§

fn eq(&self, other: &Cow<'a, str>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<String> for &'a BStr

§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<String> for BStr

§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<Vec<u8>> for &'a BStr

§

fn eq(&self, other: &Vec<u8>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<Vec<u8>> for BStr

§

fn eq(&self, other: &Vec<u8>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<str> for BStr

§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for BStr

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialOrd<&'a [u8]> for BStr

§

fn partial_cmp(&self, other: &&'a [u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<&'a BStr> for BString

§

fn partial_cmp(&self, other: &&'a BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<&'a BStr> for Vec<u8>

§

fn partial_cmp(&self, other: &&'a BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<&'a str> for BStr

§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<[u8]> for BStr

§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BStr> for &'a [u8]

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BStr> for &'a str

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BStr> for [u8]

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BStr> for BString

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BStr> for Vec<u8>

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BStr> for str

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for &'a BStr

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for BStr

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<String> for &'a BStr

§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<String> for BStr

§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<Vec<u8>> for &'a BStr

§

fn partial_cmp(&self, other: &Vec<u8>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<Vec<u8>> for BStr

§

fn partial_cmp(&self, other: &Vec<u8>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<str> for BStr

§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd for BStr

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl ToOwned for BStr

§

type Owned = BString

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> BString

Creates owned data from borrowed data, usually by cloning. Read more
1.63.0 · source§

fn clone_into(&self, target: &mut Self::Owned)

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

impl<'a> TryFrom<&'a BStr> for &'a str

§

type Error = Utf8Error

The type returned in the event of a conversion error.
§

fn try_from(s: &'a BStr) -> Result<&'a str, Utf8Error>

Performs the conversion.
§

impl Eq for BStr

Auto Trait Implementations§

§

impl RefUnwindSafe for BStr

§

impl Send for BStr

§

impl !Sized for BStr

§

impl Sync for BStr

§

impl Unpin for BStr

§

impl UnwindSafe for BStr

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
\ No newline at end of file diff --git a/ba2/struct.BString.html b/ba2/struct.BString.html new file mode 100644 index 0000000..a97a42a --- /dev/null +++ b/ba2/struct.BString.html @@ -0,0 +1,3156 @@ +BString in ba2 - Rust

Struct ba2::BString

pub struct BString { /* private fields */ }
Expand description

A wrapper for Vec<u8> that provides convenient string oriented trait +impls.

+

A BString has ownership over its contents and corresponds to +a growable or shrinkable buffer. Its borrowed counterpart is a +BStr, called a byte string slice.

+

Using a BString is just like using a Vec<u8>, since BString +implements Deref to Vec<u8>. So all methods available on Vec<u8> +are also available on BString.

+

Examples

+

You can create a new BString from a Vec<u8> via a From impl:

+ +
use bstr::BString;
+
+let s = BString::from("Hello, world!");
+

Deref

+

The BString type implements Deref and DerefMut, where the target +types are &Vec<u8> and &mut Vec<u8>, respectively. Deref permits all of the +methods defined on Vec<u8> to be implicitly callable on any BString.

+

For more information about how deref works, see the documentation for the +std::ops::Deref +trait.

+

Representation

+

A BString has the same representation as a Vec<u8> and a String. +That is, it is made up of three word sized components: a pointer to a +region of memory containing the bytes, a length and a capacity.

+

Implementations§

§

impl BString

pub const fn new(bytes: Vec<u8>) -> BString

Constructs a new BString from the given Vec.

+
Examples
+
use bstr::BString;
+
+let mut b = BString::new(Vec::with_capacity(10));
+

This function is const:

+ +
use bstr::BString;
+
+const B: BString = BString::new(vec![]);
+

Methods from Deref<Target = Vec<u8>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Shrinks the capacity of the vector as much as possible.

+

It will drop down as close as possible to the length but the allocator +may still inform the vector that there is space for a few more elements.

+
Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

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

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering, but is O(1). +If you need to preserve the element order, use remove instead.

+
Panics
+

Panics if index is out of bounds.

+
Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
Panics
+

Panics if index > len.

+
Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
Panics
+

Panics if index is out of bounds.

+
Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Appends an element to the back of a collection.

+
Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

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

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Moves all the elements of other into self, leaving other empty.

+
Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>where + A: Clone,

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
Panics
+

Panics if at > len.

+
Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)where + F: FnMut() -> T,

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

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

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)where + R: RangeBounds<usize>,

Copies elements from src range to the end of the vector.

+
Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>where + F: FnMut(&mut T) -> bool,

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

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

source

pub fn flatten(&self) -> &[T]

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

Takes a &[[T; N]], and flattens it to a &[T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].flatten(),
+    [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+
source

pub fn flatten_mut(&mut self) -> &mut [T]

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

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.flatten_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the last item in the slice.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

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

Returns the first N elements of the slice, or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

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

Returns a mutable reference to the first N elements of the slice, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

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

Returns the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

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

Returns a mutable reference to the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

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

Returns the last N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk::<2>() {
+    assert_eq!(last, &[1, 2]);
+    assert_eq!(elements, &[0]);
+}
+
source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

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

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

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

Returns the last element of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

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

Returns a mutable pointer to the last item in the slice.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Panics
+

Panics if a or b are out of bounds.

+
Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

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

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
Panics
+

Panics if size is 0.

+
Examples
+
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

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

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

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

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

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

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

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

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

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

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

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

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

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

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

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

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

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

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
source

pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>where + F: FnMut(&T, &T) -> bool,

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

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
source

pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>where + F: FnMut(&T, &T) -> bool,

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

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

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

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

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

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])

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

Divides one slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.split_array_ref::<0>();
+   assert_eq!(left, &[]);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<2>();
+    assert_eq!(left, &[1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<6>();
+    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub fn split_array_mut<const N: usize>(&mut self) -> (&mut [T; N], &mut [T])

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

Divides one mutable slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.split_array_mut::<2>();
+assert_eq!(left, &mut [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])

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

Divides one slice into an array and a remainder slice at an index from +the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index len - N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.rsplit_array_ref::<0>();
+   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+   assert_eq!(right, &[]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<2>();
+    assert_eq!(left, [1, 2, 3, 4]);
+    assert_eq!(right, &[5, 6]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<6>();
+    assert_eq!(left, []);
+    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
+
source

pub fn rsplit_array_mut<const N: usize>(&mut self) -> (&mut [T], &mut [T; N])

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

Divides one mutable slice into an array and a remainder slice at an +index from the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.rsplit_array_mut::<4>();
+assert_eq!(left, [1, 0]);
+assert_eq!(right, &mut [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>where + F: FnMut(&T) -> bool,

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

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are resent in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>where + F: FnMut(&T) -> bool,

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

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are resent in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> boolwhere + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> boolwhere + T: PartialEq,

Returns true if needle is a prefix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> boolwhere + T: PartialEq,

Returns true if needle is a suffix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice.

+

If the slice does not start with prefix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice.

+

If the slice does not end with suffix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])where + T: Ord,

Reorder the slice such that the element at index is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median
+v.select_nth_unstable(2);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median as if the slice were sorted in descending order.
+v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Return the median as if the array were sorted according to absolute value.
+v.select_nth_unstable_by_key(2, |a| a.abs());
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])where + T: PartialEq,

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

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T, &mut T) -> bool,

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

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T) -> K, + K: PartialEq,

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

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)where + T: Clone,

Fills self with elements by cloning value.

+
Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

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

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
Examples
+
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    use std::simd::f32x4;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

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

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> boolwhere + T: PartialOrd,

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

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> boolwhere + F: FnMut(&'a T, &'a T) -> Option<Ordering>,

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

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine the ordering of two elements. Apart from that, it’s equivalent to +is_sorted; see its documentation for more information.

+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> boolwhere + F: FnMut(&'a T) -> K, + K: PartialOrd,

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

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usizewhere + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<R, 'a>(self: &mut &'a [T], range: R) -> Option<&'a [T]>where + R: OneSidedRange<usize>,

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

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<R, 'a>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>where + R: OneSidedRange<usize>,

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

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

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

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

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

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

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

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

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

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

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

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

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

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

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

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

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

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
source

pub fn trim_ascii_start(&self) -> &[u8]

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

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
source

pub fn trim_ascii_end(&self) -> &[u8]

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

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
source

pub fn trim_ascii(&self) -> &[u8]

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

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn as_str(&self) -> &str

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

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

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

Views this slice of ASCII characters as a slice of u8 bytes.

+
source

pub fn sort_floats(&mut self)

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

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn sort_floats(&mut self)

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

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn sort(&mut self)where + T: Ord,

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>where + T: Clone,

Copies self into a new Vec.

+
Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>where + A: Allocator, + T: Clone,

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

Copies self into a new Vec with an allocator.

+
Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>where + T: Copy,

Creates a vector by copying a slice n times.

+
Panics
+

This function will panic if the capacity would overflow.

+
Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

§

impl AsMut<[u8]> for BString

§

fn as_mut(&mut self) -> &mut [u8]

Converts this type into a mutable reference of the (usually inferred) input type.
§

impl AsMut<BStr> for BString

§

fn as_mut(&mut self) -> &mut BStr

Converts this type into a mutable reference of the (usually inferred) input type.
§

impl AsRef<[u8]> for BString

§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
§

impl AsRef<BStr> for BString

§

fn as_ref(&self) -> &BStr

Converts this type into a shared reference of the (usually inferred) input type.
§

impl Borrow<[u8]> for BString

§

fn borrow(&self) -> &[u8]

Immutably borrows from an owned value. Read more
§

impl Borrow<BStr> for BString

§

fn borrow(&self) -> &BStr

Immutably borrows from an owned value. Read more
§

impl BorrowMut<[u8]> for BString

§

fn borrow_mut(&mut self) -> &mut [u8]

Mutably borrows from an owned value. Read more
§

impl BorrowMut<BStr> for BString

§

fn borrow_mut(&mut self) -> &mut BStr

Mutably borrows from an owned value. Read more
§

impl Clone for BString

§

fn clone(&self) -> BString

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for BString

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for BString

§

fn default() -> BString

Returns the “default value” for a type. Read more
§

impl Deref for BString

§

type Target = Vec<u8>

The resulting type after dereferencing.
§

fn deref(&self) -> &Vec<u8>

Dereferences the value.
§

impl DerefMut for BString

§

fn deref_mut(&mut self) -> &mut Vec<u8>

Mutably dereferences the value.
§

impl Display for BString

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<'a> From<&'a [u8]> for BString

§

fn from(s: &'a [u8]) -> BString

Converts to this type from the input type.
§

impl<'a, const N: usize> From<&'a [u8; N]> for BString

§

fn from(s: &'a [u8; N]) -> BString

Converts to this type from the input type.
§

impl<'a> From<&'a BStr> for BString

§

fn from(s: &'a BStr) -> BString

Converts to this type from the input type.
§

impl<'a> From<&'a str> for BString

§

fn from(s: &'a str) -> BString

Converts to this type from the input type.
§

impl<const N: usize> From<[u8; N]> for BString

§

fn from(s: [u8; N]) -> BString

Converts to this type from the input type.
§

impl From<BString> for Vec<u8>

§

fn from(s: BString) -> Vec<u8>

Converts to this type from the input type.
§

impl From<String> for BString

§

fn from(s: String) -> BString

Converts to this type from the input type.
§

impl From<Vec<u8>> for BString

§

fn from(s: Vec<u8>) -> BString

Converts to this type from the input type.
§

impl<'a> FromIterator<&'a [u8]> for BString

§

fn from_iter<T>(iter: T) -> BStringwhere + T: IntoIterator<Item = &'a [u8]>,

Creates a value from an iterator. Read more
§

impl<'a> FromIterator<&'a BStr> for BString

§

fn from_iter<T>(iter: T) -> BStringwhere + T: IntoIterator<Item = &'a BStr>,

Creates a value from an iterator. Read more
§

impl<'a> FromIterator<&'a str> for BString

§

fn from_iter<T>(iter: T) -> BStringwhere + T: IntoIterator<Item = &'a str>,

Creates a value from an iterator. Read more
§

impl FromIterator<BString> for BString

§

fn from_iter<T>(iter: T) -> BStringwhere + T: IntoIterator<Item = BString>,

Creates a value from an iterator. Read more
§

impl FromIterator<char> for BString

§

fn from_iter<T>(iter: T) -> BStringwhere + T: IntoIterator<Item = char>,

Creates a value from an iterator. Read more
§

impl FromIterator<u8> for BString

§

fn from_iter<T>(iter: T) -> BStringwhere + T: IntoIterator<Item = u8>,

Creates a value from an iterator. Read more
§

impl Hash for BString

§

fn hash<__H>(&self, state: &mut __H)where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Ord for BString

§

fn cmp(&self, other: &BString) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl<'a, 'b> PartialEq<&'a [u8]> for BString

§

fn eq(&self, other: &&'a [u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<&'a BStr> for BString

§

fn eq(&self, other: &&'a BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<&'a str> for BString

§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<[u8]> for BString

§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BStr> for BString

§

fn eq(&self, other: &BStr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for &'a [u8]

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for &'a BStr

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for &'a str

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for [u8]

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for BStr

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for Vec<u8>

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<BString> for str

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<String> for BString

§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<Vec<u8>> for BString

§

fn eq(&self, other: &Vec<u8>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialEq<str> for BString

§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for BString

§

fn eq(&self, other: &BString) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, 'b> PartialOrd<&'a [u8]> for BString

§

fn partial_cmp(&self, other: &&'a [u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<&'a BStr> for BString

§

fn partial_cmp(&self, other: &&'a BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<&'a str> for BString

§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<[u8]> for BString

§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BStr> for BString

§

fn partial_cmp(&self, other: &BStr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for &'a [u8]

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for &'a BStr

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for &'a str

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for [u8]

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for BStr

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for Vec<u8>

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<BString> for str

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<String> for BString

§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<Vec<u8>> for BString

§

fn partial_cmp(&self, other: &Vec<u8>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a, 'b> PartialOrd<str> for BString

§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd for BString

§

fn partial_cmp(&self, other: &BString) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<'a> TryFrom<&'a BString> for &'a str

§

type Error = Utf8Error

The type returned in the event of a conversion error.
§

fn try_from(s: &'a BString) -> Result<&'a str, Utf8Error>

Performs the conversion.
§

impl Eq for BString

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/struct.Borrowed.html b/ba2/struct.Borrowed.html new file mode 100644 index 0000000..aa5a510 --- /dev/null +++ b/ba2/struct.Borrowed.html @@ -0,0 +1,13 @@ +Borrowed in ba2 - Rust

Struct ba2::Borrowed

source ·
pub struct Borrowed<'borrow>(pub &'borrow [u8]);
Expand description

Makes a shallow copy of the input.

+

The lifetime of the result is tied to the input buffer.

+

Tuple Fields§

§0: &'borrow [u8]

Trait Implementations§

source§

impl<'bytes> Reader<Borrowed<'bytes>> for Archive<'bytes>

§

type Error = Error

§

type Item = (Archive<'bytes>, Options)

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Borrowed<'bytes>> for Archive<'bytes>

§

type Error = Error

§

type Item = (Archive<'bytes>, Options)

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Borrowed<'bytes>> for Archive<'bytes>

§

type Error = Error

§

type Item = Archive<'bytes>

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Borrowed<'bytes>> for File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> ReaderWithOptions<Borrowed<'bytes>> for File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

§

type Options = ReadOptions

source§

fn read(source: Borrowed<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl<'bytes> ReaderWithOptions<Borrowed<'bytes>> for File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

§

type Options = ReadOptions

source§

fn read(source: Borrowed<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.

Auto Trait Implementations§

§

impl<'borrow> RefUnwindSafe for Borrowed<'borrow>

§

impl<'borrow> Send for Borrowed<'borrow>

§

impl<'borrow> Sync for Borrowed<'borrow>

§

impl<'borrow> Unpin for Borrowed<'borrow>

§

impl<'borrow> UnwindSafe for Borrowed<'borrow>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/struct.Copied.html b/ba2/struct.Copied.html new file mode 100644 index 0000000..c914217 --- /dev/null +++ b/ba2/struct.Copied.html @@ -0,0 +1,13 @@ +Copied in ba2 - Rust

Struct ba2::Copied

source ·
pub struct Copied<'copy>(pub &'copy [u8]);
Expand description

Makes a deep copy of the input.

+

The lifetime of the result is independent of the input buffer.

+

Tuple Fields§

§0: &'copy [u8]

Trait Implementations§

source§

impl<'bytes> Reader<Copied<'bytes>> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Copied<'bytes>> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Copied<'bytes>> for Archive<'static>

§

type Error = Error

§

type Item = Archive<'static>

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Copied<'bytes>> for File<'static>

§

type Error = Error

§

type Item = File<'static>

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> ReaderWithOptions<Copied<'bytes>> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: Copied<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl<'bytes> ReaderWithOptions<Copied<'bytes>> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: Copied<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.

Auto Trait Implementations§

§

impl<'copy> RefUnwindSafe for Copied<'copy>

§

impl<'copy> Send for Copied<'copy>

§

impl<'copy> Sync for Copied<'copy>

§

impl<'copy> Unpin for Copied<'copy>

§

impl<'copy> UnwindSafe for Copied<'copy>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes3/archive/struct.Archive.html b/ba2/tes3/archive/struct.Archive.html new file mode 100644 index 0000000..67d5b44 --- /dev/null +++ b/ba2/tes3/archive/struct.Archive.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes3/struct.Archive.html...

+ + + \ No newline at end of file diff --git a/ba2/tes3/archive/struct.Key.html b/ba2/tes3/archive/struct.Key.html new file mode 100644 index 0000000..c9769ef --- /dev/null +++ b/ba2/tes3/archive/struct.Key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes3/struct.ArchiveKey.html...

+ + + \ No newline at end of file diff --git a/ba2/tes3/enum.Error.html b/ba2/tes3/enum.Error.html new file mode 100644 index 0000000..7e2200b --- /dev/null +++ b/ba2/tes3/enum.Error.html @@ -0,0 +1,16 @@ +Error in ba2::tes3 - Rust

Enum ba2::tes3::Error

source ·
#[non_exhaustive]
pub enum Error { + IntegralTruncation, + InvalidMagic(u32), + Io(Error), +}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

IntegralTruncation

§

InvalidMagic(u32)

§

Io(Error)

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<TryFromIntError> for Error

source§

fn from(_: TryFromIntError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes3/file/struct.File.html b/ba2/tes3/file/struct.File.html new file mode 100644 index 0000000..af7f67d --- /dev/null +++ b/ba2/tes3/file/struct.File.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes3/struct.File.html...

+ + + \ No newline at end of file diff --git a/ba2/tes3/fn.hash_file.html b/ba2/tes3/fn.hash_file.html new file mode 100644 index 0000000..fe0dc7a --- /dev/null +++ b/ba2/tes3/fn.hash_file.html @@ -0,0 +1,2 @@ +hash_file in ba2::tes3 - Rust

Function ba2::tes3::hash_file

source ·
pub fn hash_file(path: &BStr) -> (FileHash, BString)
Expand description

Produces a hash using the given path.

+
\ No newline at end of file diff --git a/ba2/tes3/fn.hash_file_in_place.html b/ba2/tes3/fn.hash_file_in_place.html new file mode 100644 index 0000000..2f263b9 --- /dev/null +++ b/ba2/tes3/fn.hash_file_in_place.html @@ -0,0 +1,3 @@ +hash_file_in_place in ba2::tes3 - Rust

Function ba2::tes3::hash_file_in_place

source ·
pub fn hash_file_in_place(path: &mut BString) -> FileHash
Expand description

Produces a hash using the given path.

+

The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.

+
\ No newline at end of file diff --git a/ba2/tes3/hashing/fn.hash_file.html b/ba2/tes3/hashing/fn.hash_file.html new file mode 100644 index 0000000..d24820c --- /dev/null +++ b/ba2/tes3/hashing/fn.hash_file.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes3/fn.hash_file.html...

+ + + \ No newline at end of file diff --git a/ba2/tes3/hashing/fn.hash_file_in_place.html b/ba2/tes3/hashing/fn.hash_file_in_place.html new file mode 100644 index 0000000..6c7b749 --- /dev/null +++ b/ba2/tes3/hashing/fn.hash_file_in_place.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes3/fn.hash_file_in_place.html...

+ + + \ No newline at end of file diff --git a/ba2/tes3/hashing/struct.FileHash.html b/ba2/tes3/hashing/struct.FileHash.html new file mode 100644 index 0000000..5d8a915 --- /dev/null +++ b/ba2/tes3/hashing/struct.FileHash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes3/struct.FileHash.html...

+ + + \ No newline at end of file diff --git a/ba2/tes3/hashing/struct.Hash.html b/ba2/tes3/hashing/struct.Hash.html new file mode 100644 index 0000000..651fedb --- /dev/null +++ b/ba2/tes3/hashing/struct.Hash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes3/struct.Hash.html...

+ + + \ No newline at end of file diff --git a/ba2/tes3/index.html b/ba2/tes3/index.html new file mode 100644 index 0000000..7776b72 --- /dev/null +++ b/ba2/tes3/index.html @@ -0,0 +1,35 @@ +ba2::tes3 - Rust

Module ba2::tes3

source ·
Expand description

TES III: Morrowind

+

“Ahh yes, we’ve been expecting you. You’ll have to be recorded before you’re officially released. There are a few ways we can do this, and the choice is yours.”

+

This format debuted and sunset with Morrowind. It is the simplest of all the formats, using no compression or special tricks to organize the data.

+

Reading

+
use ba2::{
+    prelude::*,
+    tes3::{Archive, ArchiveKey},
+};
+use std::{fs, path::Path};
+
+fn example() -> Option<()> {
+    let path = Path::new("path/to/morrowind/Data Files/Morrowind.bsa");
+    let archive = Archive::read(path).ok()?;
+    let key: ArchiveKey = b"icons/gold.dds".into();
+    let file = archive.get(&key)?;
+    let mut dst = fs::File::create("gold.dds").ok()?;
+    file.write(&mut dst).ok()?;
+    Some(())
+}
+

Writing

+
use ba2::{
+    prelude::*,
+    tes3::{Archive, ArchiveKey, File},
+};
+use std::fs;
+
+fn example() -> Option<()> {
+    let file: File = b"Hello world!\n".into();
+    let key: ArchiveKey = b"hello.txt".into();
+    let archive: Archive = [(key, file)].into_iter().collect();
+    let mut dst = fs::File::create("example.bsa").ok()?;
+    archive.write(&mut dst).ok()?;
+    Some(())
+}
+

Structs

  • Represents the TES3 revision of the bsa format.
  • A key for indexing into the relevant mapping.
  • Represents a file within the TES3 virtual filesystem.
  • See also Hash.
  • The underlying hash object used to uniquely identify objects within the archive.

Enums

Functions

Type Aliases

\ No newline at end of file diff --git a/ba2/tes3/sidebar-items.js b/ba2/tes3/sidebar-items.js new file mode 100644 index 0000000..43ab054 --- /dev/null +++ b/ba2/tes3/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Error"],"fn":["hash_file","hash_file_in_place"],"struct":["Archive","ArchiveKey","File","FileHash","Hash"],"type":["Result"]}; \ No newline at end of file diff --git a/ba2/tes3/struct.Archive.html b/ba2/tes3/struct.Archive.html new file mode 100644 index 0000000..ad98577 --- /dev/null +++ b/ba2/tes3/struct.Archive.html @@ -0,0 +1,26 @@ +Archive in ba2::tes3 - Rust

Struct ba2::tes3::Archive

source ·
pub struct Archive<'bytes> { /* private fields */ }
Expand description

Represents the TES3 revision of the bsa format.

+

Implementations§

source§

impl<'bytes> Archive<'bytes>

source

pub fn clear(&mut self)

source

pub fn get<K>(&self, key: &K) -> Option<&File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn get_key_value<K>(&self, key: &K) -> Option<(&Key<'bytes>, &File<'bytes>)>where + K: Borrow<FileHash>,

source

pub fn get_mut<K>(&mut self, key: &K) -> Option<&mut File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn insert<K>(&mut self, key: K, value: File<'bytes>) -> Option<File<'bytes>>where + K: Into<Key<'bytes>>,

source

pub fn is_empty(&self) -> bool

source

pub fn iter(&self) -> impl Iterator<Item = (&Key<'bytes>, &File<'bytes>)>

source

pub fn iter_mut( + &mut self +) -> impl Iterator<Item = (&Key<'bytes>, &mut File<'bytes>)>

source

pub fn keys(&self) -> impl Iterator<Item = &Key<'bytes>>

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source

pub fn remove<K>(&mut self, key: &K) -> Option<File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn remove_entry<K>( + &mut self, + key: &K +) -> Option<(Key<'bytes>, File<'bytes>)>where + K: Borrow<FileHash>,

source

pub fn values(&self) -> impl Iterator<Item = &File<'bytes>>

source

pub fn values_mut(&mut self) -> impl Iterator<Item = &mut File<'bytes>>

source§

impl<'bytes> Archive<'bytes>

source

pub fn write<Out>(&self, stream: &mut Out) -> Result<()>where + Out: ?Sized + Write,

Trait Implementations§

source§

impl<'bytes> Clone for Archive<'bytes>

source§

fn clone(&self) -> Archive<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Archive<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Archive<'bytes>

source§

fn default() -> Archive<'bytes>

Returns the “default value” for a type. Read more
source§

impl<'bytes> FromIterator<(Key<'bytes>, File<'bytes>)> for Archive<'bytes>

source§

fn from_iter<T>(iter: T) -> Selfwhere + T: IntoIterator<Item = (Key<'bytes>, File<'bytes>)>,

Creates a value from an iterator. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this Archive<'bytes>

§

type Item = <&'this BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this mut Archive<'bytes>

§

type Item = <&'this mut BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this mut BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes> IntoIterator for Archive<'bytes>

§

type Item = <BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl Reader<&File> for Archive<'static>

§

type Error = Error

§

type Item = Archive<'static>

source§

fn read(source: &File) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl Reader<&Path> for Archive<'static>

§

type Error = Error

§

type Item = Archive<'static>

source§

fn read(source: &Path) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Borrowed<'bytes>> for Archive<'bytes>

§

type Error = Error

§

type Item = Archive<'bytes>

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Copied<'bytes>> for Archive<'static>

§

type Error = Error

§

type Item = Archive<'static>

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Archive<'bytes>

§

impl<'bytes> Send for Archive<'bytes>

§

impl<'bytes> Sync for Archive<'bytes>

§

impl<'bytes> Unpin for Archive<'bytes>

§

impl<'bytes> UnwindSafe for Archive<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes3/struct.ArchiveKey.html b/ba2/tes3/struct.ArchiveKey.html new file mode 100644 index 0000000..3f04161 --- /dev/null +++ b/ba2/tes3/struct.ArchiveKey.html @@ -0,0 +1,21 @@ +ArchiveKey in ba2::tes3 - Rust

Struct ba2::tes3::ArchiveKey

source ·
pub struct ArchiveKey<'bytes> { /* private fields */ }
Expand description

A key for indexing into the relevant mapping.

+

Implementations§

source§

impl<'bytes> Key<'bytes>

source

pub fn hash(&self) -> &FileHash

source

pub fn name(&self) -> &BStr

Trait Implementations§

source§

impl<'bytes> Borrow<FileHash> for Key<'bytes>

source§

fn borrow(&self) -> &FileHash

Immutably borrows from an owned value. Read more
source§

impl<'bytes> Clone for Key<'bytes>

source§

fn clone(&self) -> Key<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Key<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Key<'bytes>

source§

fn default() -> Key<'bytes>

Returns the “default value” for a type. Read more
source§

impl From<FileHash> for Key<'static>

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl<T> From<T> for Key<'static>where + T: Into<BString>,

source§

fn from(value: T) -> Self

Converts to this type from the input type.
source§

impl<'bytes> Ord for Key<'bytes>

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'bytes> PartialEq for Key<'bytes>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'bytes> PartialOrd for Key<'bytes>

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'bytes> Eq for Key<'bytes>

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Key<'bytes>

§

impl<'bytes> Send for Key<'bytes>

§

impl<'bytes> Sync for Key<'bytes>

§

impl<'bytes> Unpin for Key<'bytes>

§

impl<'bytes> UnwindSafe for Key<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes3/struct.File.html b/ba2/tes3/struct.File.html new file mode 100644 index 0000000..96bd50d --- /dev/null +++ b/ba2/tes3/struct.File.html @@ -0,0 +1,14 @@ +File in ba2::tes3 - Rust

Struct ba2::tes3::File

source ·
pub struct File<'bytes> { /* private fields */ }
Expand description

Represents a file within the TES3 virtual filesystem.

+

Implementations§

source§

impl<'bytes> File<'bytes>

source

pub fn as_bytes(&self) -> &[u8]

source

pub fn as_ptr(&self) -> *const u8

source

pub fn into_owned(self) -> File<'static>

source

pub fn is_empty(&self) -> bool

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source§

impl<'bytes> File<'bytes>

source

pub fn write<Out>(&self, stream: &mut Out) -> Result<()>where + Out: ?Sized + Write,

Trait Implementations§

source§

impl<'bytes> Clone for File<'bytes>

source§

fn clone(&self) -> File<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for File<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for File<'bytes>

source§

fn default() -> File<'bytes>

Returns the “default value” for a type. Read more
source§

impl<'bytes> From<&'bytes [u8]> for File<'bytes>

source§

fn from(value: &'bytes [u8]) -> Self

Converts to this type from the input type.
source§

impl<'bytes, const N: usize> From<&'bytes [u8; N]> for File<'bytes>

source§

fn from(value: &'bytes [u8; N]) -> Self

Converts to this type from the input type.
source§

impl From<Box<[u8]>> for File<'static>

source§

fn from(value: Box<[u8]>) -> Self

Converts to this type from the input type.
source§

impl Reader<&File> for File<'static>

§

type Error = Error

§

type Item = File<'static>

source§

fn read(source: &File) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl Reader<&Path> for File<'static>

§

type Error = Error

§

type Item = File<'static>

source§

fn read(source: &Path) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Borrowed<'bytes>> for File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Copied<'bytes>> for File<'static>

§

type Error = Error

§

type Item = File<'static>

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for File<'bytes>

§

impl<'bytes> Send for File<'bytes>

§

impl<'bytes> Sync for File<'bytes>

§

impl<'bytes> Unpin for File<'bytes>

§

impl<'bytes> UnwindSafe for File<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes3/struct.FileHash.html b/ba2/tes3/struct.FileHash.html new file mode 100644 index 0000000..9387bf6 --- /dev/null +++ b/ba2/tes3/struct.FileHash.html @@ -0,0 +1,28 @@ +FileHash in ba2::tes3 - Rust

Struct ba2::tes3::FileHash

source ·
pub struct FileHash(/* private fields */);
Expand description

See also Hash.

+

Implementations§

source§

impl FileHash

source

pub fn new() -> Self

Methods from Deref<Target = Hash>§

source

pub fn numeric(&self) -> u64

Trait Implementations§

source§

impl AsMut<Hash> for FileHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for FileHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<'bytes> Borrow<FileHash> for Key<'bytes>

source§

fn borrow(&self) -> &FileHash

Immutably borrows from an owned value. Read more
source§

impl Borrow<Hash> for FileHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for FileHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl Clone for FileHash

source§

fn clone(&self) -> FileHash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for FileHash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for FileHash

source§

fn default() -> FileHash

Returns the “default value” for a type. Read more
source§

impl Deref for FileHash

§

type Target = Hash

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for FileHash

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl From<FileHash> for Hash

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<FileHash> for Key<'static>

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for FileHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl Ord for FileHash

source§

fn cmp(&self, other: &FileHash) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<FileHash> for Hash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for FileHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for FileHash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<FileHash> for Hash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for FileHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for FileHash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for FileHash

source§

impl Eq for FileHash

source§

impl StructuralEq for FileHash

source§

impl StructuralPartialEq for FileHash

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes3/struct.Hash.html b/ba2/tes3/struct.Hash.html new file mode 100644 index 0000000..725c916 --- /dev/null +++ b/ba2/tes3/struct.Hash.html @@ -0,0 +1,31 @@ +Hash in ba2::tes3 - Rust

Struct ba2::tes3::Hash

source ·
#[repr(C)]
pub struct Hash { + pub lo: u32, + pub hi: u32, +}
Expand description

The underlying hash object used to uniquely identify objects within the archive.

+

Fields§

§lo: u32§hi: u32

Implementations§

source§

impl Hash

source

pub fn new() -> Self

source

pub fn numeric(&self) -> u64

Trait Implementations§

source§

impl AsMut<Hash> for FileHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for FileHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Borrow<Hash> for FileHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for FileHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl Clone for Hash

source§

fn clone(&self) -> Hash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Hash

source§

fn default() -> Hash

Returns the “default value” for a type. Read more
source§

impl From<FileHash> for Hash

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for FileHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl Ord for Hash

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<FileHash> for Hash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for FileHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Hash

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<FileHash> for Hash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for FileHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for Hash

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Hash

source§

impl Eq for Hash

Auto Trait Implementations§

§

impl RefUnwindSafe for Hash

§

impl Send for Hash

§

impl Sync for Hash

§

impl Unpin for Hash

§

impl UnwindSafe for Hash

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes3/type.Result.html b/ba2/tes3/type.Result.html new file mode 100644 index 0000000..a4d4508 --- /dev/null +++ b/ba2/tes3/type.Result.html @@ -0,0 +1,6 @@ +Result in ba2::tes3 - Rust

Type Alias ba2::tes3::Result

source ·
pub type Result<T> = Result<T, Error>;

Aliased Type§

enum Result<T> {
+    Ok(T),
+    Err(Error),
+}

Variants§

§1.0.0

Ok(T)

Contains the success value

+
§1.0.0

Err(Error)

Contains the error value

+
\ No newline at end of file diff --git a/ba2/tes4/archive/struct.Archive.html b/ba2/tes4/archive/struct.Archive.html new file mode 100644 index 0000000..474c821 --- /dev/null +++ b/ba2/tes4/archive/struct.Archive.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.Archive.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/archive/struct.Flags.html b/ba2/tes4/archive/struct.Flags.html new file mode 100644 index 0000000..3cdce3c --- /dev/null +++ b/ba2/tes4/archive/struct.Flags.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.ArchiveFlags.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/archive/struct.Key.html b/ba2/tes4/archive/struct.Key.html new file mode 100644 index 0000000..b3150f7 --- /dev/null +++ b/ba2/tes4/archive/struct.Key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.ArchiveKey.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/archive/struct.Options.html b/ba2/tes4/archive/struct.Options.html new file mode 100644 index 0000000..de795ae --- /dev/null +++ b/ba2/tes4/archive/struct.Options.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.ArchiveOptions.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/archive/struct.OptionsBuilder.html b/ba2/tes4/archive/struct.OptionsBuilder.html new file mode 100644 index 0000000..2a82f69 --- /dev/null +++ b/ba2/tes4/archive/struct.OptionsBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.ArchiveOptionsBuilder.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/archive/struct.Types.html b/ba2/tes4/archive/struct.Types.html new file mode 100644 index 0000000..58ad9e1 --- /dev/null +++ b/ba2/tes4/archive/struct.Types.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.ArchiveTypes.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/directory/struct.Directory.html b/ba2/tes4/directory/struct.Directory.html new file mode 100644 index 0000000..ba985d5 --- /dev/null +++ b/ba2/tes4/directory/struct.Directory.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.Directory.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/directory/struct.Key.html b/ba2/tes4/directory/struct.Key.html new file mode 100644 index 0000000..ebd7a39 --- /dev/null +++ b/ba2/tes4/directory/struct.Key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.DirectoryKey.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/enum.CompressionCodec.html b/ba2/tes4/enum.CompressionCodec.html new file mode 100644 index 0000000..4fc92a9 --- /dev/null +++ b/ba2/tes4/enum.CompressionCodec.html @@ -0,0 +1,18 @@ +CompressionCodec in ba2::tes4 - Rust
#[non_exhaustive]
pub enum CompressionCodec { + Normal, +}
Expand description

Specifies the codec to use when performing compression/decompression actions on files.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Normal

The default compression codec.

+

Trait Implementations§

source§

impl Clone for CompressionCodec

source§

fn clone(&self) -> CompressionCodec

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CompressionCodec

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionCodec

source§

fn default() -> CompressionCodec

Returns the “default value” for a type. Read more
source§

impl PartialEq for CompressionCodec

source§

fn eq(&self, other: &CompressionCodec) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for CompressionCodec

source§

impl Eq for CompressionCodec

source§

impl StructuralEq for CompressionCodec

source§

impl StructuralPartialEq for CompressionCodec

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/enum.Error.html b/ba2/tes4/enum.Error.html new file mode 100644 index 0000000..518b81b --- /dev/null +++ b/ba2/tes4/enum.Error.html @@ -0,0 +1,26 @@ +Error in ba2::tes4 - Rust

Enum ba2::tes4::Error

source ·
#[non_exhaustive]
pub enum Error { + AlreadyCompressed, + AlreadyDecompressed, + DecompressionSizeMismatch { + expected: usize, + actual: usize, + }, + IntegralOverflow, + IntegralTruncation, + InvalidHeaderSize(u32), + InvalidMagic(u32), + InvalidVersion(u32), + Io(Error), + LZ4(Error), +}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

AlreadyCompressed

§

AlreadyDecompressed

§

DecompressionSizeMismatch

Fields

§expected: usize
§actual: usize
§

IntegralOverflow

§

IntegralTruncation

§

InvalidHeaderSize(u32)

§

InvalidMagic(u32)

§

InvalidVersion(u32)

§

Io(Error)

§

LZ4(Error)

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(source: Error) -> Self

Converts to this type from the input type.
source§

impl From<TryFromIntError> for Error

source§

fn from(_: TryFromIntError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/enum.Version.html b/ba2/tes4/enum.Version.html new file mode 100644 index 0000000..69e446e --- /dev/null +++ b/ba2/tes4/enum.Version.html @@ -0,0 +1,30 @@ +Version in ba2::tes4 - Rust

Enum ba2::tes4::Version

source ·
pub enum Version {
+    v103 = 103,
+    v104 = 104,
+    v105 = 105,
+}
Expand description

The archive version.

+

Each version has an impact on the abi of the TES4 archive file format.

+

Variants§

§

v103 = 103

§

v104 = 104

§

v105 = 105

Implementations§

source§

impl Version

source

pub const TES4: Self = Self::v103

The Elder Scrolls IV: Oblivion.

+
source

pub const FO3: Self = Self::v104

Fallout 3.

+
source

pub const FNV: Self = Self::v104

Fallout: New Vegas.

+
source

pub const TES5: Self = Self::v104

The Elder Scrolls V: Skyrim.

+
source

pub const SSE: Self = Self::v105

The Elder Scrolls V: Skyrim - Special Edition.

+

Trait Implementations§

source§

impl Clone for Version

source§

fn clone(&self) -> Version

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Version

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Version

source§

fn default() -> Version

Returns the “default value” for a type. Read more
source§

impl Ord for Version

source§

fn cmp(&self, other: &Version) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Version

source§

fn eq(&self, other: &Version) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Version

source§

fn partial_cmp(&self, other: &Version) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Version

source§

impl Eq for Version

source§

impl StructuralEq for Version

source§

impl StructuralPartialEq for Version

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/file/struct.CompressionOptions.html b/ba2/tes4/file/struct.CompressionOptions.html new file mode 100644 index 0000000..0953b95 --- /dev/null +++ b/ba2/tes4/file/struct.CompressionOptions.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.FileCompressionOptions.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/file/struct.CompressionOptionsBuilder.html b/ba2/tes4/file/struct.CompressionOptionsBuilder.html new file mode 100644 index 0000000..0d8938f --- /dev/null +++ b/ba2/tes4/file/struct.CompressionOptionsBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.FileCompressionOptionsBuilder.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/file/struct.File.html b/ba2/tes4/file/struct.File.html new file mode 100644 index 0000000..d50ce37 --- /dev/null +++ b/ba2/tes4/file/struct.File.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.File.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/file/struct.ReadOptions.html b/ba2/tes4/file/struct.ReadOptions.html new file mode 100644 index 0000000..ab3b3ac --- /dev/null +++ b/ba2/tes4/file/struct.ReadOptions.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.FileReadOptions.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/file/struct.ReadOptionsBuilder.html b/ba2/tes4/file/struct.ReadOptionsBuilder.html new file mode 100644 index 0000000..40f22b5 --- /dev/null +++ b/ba2/tes4/file/struct.ReadOptionsBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.FileReadOptionsBuilder.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/fn.hash_directory.html b/ba2/tes4/fn.hash_directory.html new file mode 100644 index 0000000..2dd5332 --- /dev/null +++ b/ba2/tes4/fn.hash_directory.html @@ -0,0 +1,2 @@ +hash_directory in ba2::tes4 - Rust

Function ba2::tes4::hash_directory

source ·
pub fn hash_directory(path: &BStr) -> (DirectoryHash, BString)
Expand description

Produces a hash using the given path.

+
\ No newline at end of file diff --git a/ba2/tes4/fn.hash_directory_in_place.html b/ba2/tes4/fn.hash_directory_in_place.html new file mode 100644 index 0000000..1be4d59 --- /dev/null +++ b/ba2/tes4/fn.hash_directory_in_place.html @@ -0,0 +1,3 @@ +hash_directory_in_place in ba2::tes4 - Rust
pub fn hash_directory_in_place(path: &mut BString) -> DirectoryHash
Expand description

Produces a hash using the given path.

+

The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.

+
\ No newline at end of file diff --git a/ba2/tes4/fn.hash_file.html b/ba2/tes4/fn.hash_file.html new file mode 100644 index 0000000..5d07950 --- /dev/null +++ b/ba2/tes4/fn.hash_file.html @@ -0,0 +1,2 @@ +hash_file in ba2::tes4 - Rust

Function ba2::tes4::hash_file

source ·
pub fn hash_file(path: &BStr) -> (FileHash, BString)
Expand description

Produces a hash using the given path.

+
\ No newline at end of file diff --git a/ba2/tes4/fn.hash_file_in_place.html b/ba2/tes4/fn.hash_file_in_place.html new file mode 100644 index 0000000..70830c2 --- /dev/null +++ b/ba2/tes4/fn.hash_file_in_place.html @@ -0,0 +1,3 @@ +hash_file_in_place in ba2::tes4 - Rust

Function ba2::tes4::hash_file_in_place

source ·
pub fn hash_file_in_place(path: &mut BString) -> FileHash
Expand description

Produces a hash using the given path.

+

The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.

+
\ No newline at end of file diff --git a/ba2/tes4/hashing/fn.hash_directory.html b/ba2/tes4/hashing/fn.hash_directory.html new file mode 100644 index 0000000..952d467 --- /dev/null +++ b/ba2/tes4/hashing/fn.hash_directory.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/fn.hash_directory.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/hashing/fn.hash_directory_in_place.html b/ba2/tes4/hashing/fn.hash_directory_in_place.html new file mode 100644 index 0000000..a2bef63 --- /dev/null +++ b/ba2/tes4/hashing/fn.hash_directory_in_place.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/fn.hash_directory_in_place.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/hashing/fn.hash_file.html b/ba2/tes4/hashing/fn.hash_file.html new file mode 100644 index 0000000..e0616a3 --- /dev/null +++ b/ba2/tes4/hashing/fn.hash_file.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/fn.hash_file.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/hashing/fn.hash_file_in_place.html b/ba2/tes4/hashing/fn.hash_file_in_place.html new file mode 100644 index 0000000..d2bb6a9 --- /dev/null +++ b/ba2/tes4/hashing/fn.hash_file_in_place.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/fn.hash_file_in_place.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/hashing/struct.DirectoryHash.html b/ba2/tes4/hashing/struct.DirectoryHash.html new file mode 100644 index 0000000..26fcfde --- /dev/null +++ b/ba2/tes4/hashing/struct.DirectoryHash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.DirectoryHash.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/hashing/struct.FileHash.html b/ba2/tes4/hashing/struct.FileHash.html new file mode 100644 index 0000000..aeff3e2 --- /dev/null +++ b/ba2/tes4/hashing/struct.FileHash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.FileHash.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/hashing/struct.Hash.html b/ba2/tes4/hashing/struct.Hash.html new file mode 100644 index 0000000..7154b90 --- /dev/null +++ b/ba2/tes4/hashing/struct.Hash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ba2/tes4/struct.Hash.html...

+ + + \ No newline at end of file diff --git a/ba2/tes4/index.html b/ba2/tes4/index.html new file mode 100644 index 0000000..065e2be --- /dev/null +++ b/ba2/tes4/index.html @@ -0,0 +1,49 @@ +ba2::tes4 - Rust

Module ba2::tes4

source ·
Expand description

TES IV: Oblivion

+

“You … I’ve seen you… Let me see your face… You are the one from my dreams… Then the stars were right, and this is the day. Gods give me strength.”

+

This format debuted with Oblivion and sunset with Skyrim: SSE. This is the first format to introduce compression, and primarily utilizes zlib/lz4 for this purpose. Unlike other formats, tes4 utilizes a split architecture where files and directories are tracked as separate paths, rather than combined.

+

Reading

+
use ba2::{
+    prelude::*,
+    tes4::{Archive, ArchiveKey, DirectoryKey, FileCompressionOptions},
+};
+use std::{fs, path::Path};
+
+fn example() -> Option<()> {
+    let path = Path::new("path/to/oblivion/Data/Oblivion - Voices2.bsa");
+    let (archive, meta) = Archive::read(path).ok()?;
+    let file = archive
+        .get(&ArchiveKey::from(b"sound/voice/oblivion.esm/imperial/m"))?
+        .get(&DirectoryKey::from(
+            b"testtoddquest_testtoddhappy_00027fa2_1.mp3",
+        ))?;
+    let mut dst = fs::File::create("happy.mp3").ok()?;
+    let options: FileCompressionOptions = meta.into();
+    file.write(&mut dst, &options).ok()?;
+    Some(())
+}
+

Writing

+
use ba2::{
+    prelude::*,
+    tes4::{
+        Archive, ArchiveKey, ArchiveOptions, ArchiveTypes, Directory, DirectoryKey, File, Version,
+    },
+};
+use std::fs;
+
+fn example() -> Option<()> {
+    let file = File::from_decompressed(b"Hello world!\n");
+    let directory: Directory = [(DirectoryKey::from(b"hello.txt"), file)]
+        .into_iter()
+        .collect();
+    let archive: Archive = [(ArchiveKey::from(b"misc"), directory)]
+        .into_iter()
+        .collect();
+    let mut dst = fs::File::create("example.bsa").ok()?;
+    let options = ArchiveOptions::builder()
+        .types(ArchiveTypes::MISC)
+        .version(Version::SSE)
+        .build();
+    archive.write(&mut dst, &options).ok()?;
+    Some(())
+}
+

Structs

Enums

Functions

Type Aliases

\ No newline at end of file diff --git a/ba2/tes4/sidebar-items.js b/ba2/tes4/sidebar-items.js new file mode 100644 index 0000000..3ac7bfd --- /dev/null +++ b/ba2/tes4/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CompressionCodec","Error","Version"],"fn":["hash_directory","hash_directory_in_place","hash_file","hash_file_in_place"],"struct":["Archive","ArchiveFlags","ArchiveKey","ArchiveOptions","ArchiveOptionsBuilder","ArchiveTypes","Directory","DirectoryHash","DirectoryKey","File","FileCompressionOptions","FileCompressionOptionsBuilder","FileHash","FileReadOptions","FileReadOptionsBuilder","Hash"],"type":["Result"]}; \ No newline at end of file diff --git a/ba2/tes4/struct.Archive.html b/ba2/tes4/struct.Archive.html new file mode 100644 index 0000000..32e5c50 --- /dev/null +++ b/ba2/tes4/struct.Archive.html @@ -0,0 +1,33 @@ +Archive in ba2::tes4 - Rust

Struct ba2::tes4::Archive

source ·
pub struct Archive<'bytes> { /* private fields */ }
Expand description

Represents the TES4 revision of the bsa format.

+

Implementations§

source§

impl<'bytes> Archive<'bytes>

source

pub fn clear(&mut self)

source

pub fn get<K>(&self, key: &K) -> Option<&Directory<'bytes>>where + K: Borrow<DirectoryHash>,

source

pub fn get_key_value<K>( + &self, + key: &K +) -> Option<(&Key<'bytes>, &Directory<'bytes>)>where + K: Borrow<DirectoryHash>,

source

pub fn get_mut<K>(&mut self, key: &K) -> Option<&mut Directory<'bytes>>where + K: Borrow<DirectoryHash>,

source

pub fn insert<K>( + &mut self, + key: K, + value: Directory<'bytes> +) -> Option<Directory<'bytes>>where + K: Into<Key<'bytes>>,

source

pub fn is_empty(&self) -> bool

source

pub fn iter(&self) -> impl Iterator<Item = (&Key<'bytes>, &Directory<'bytes>)>

source

pub fn iter_mut( + &mut self +) -> impl Iterator<Item = (&Key<'bytes>, &mut Directory<'bytes>)>

source

pub fn keys(&self) -> impl Iterator<Item = &Key<'bytes>>

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source

pub fn remove<K>(&mut self, key: &K) -> Option<Directory<'bytes>>where + K: Borrow<DirectoryHash>,

source

pub fn remove_entry<K>( + &mut self, + key: &K +) -> Option<(Key<'bytes>, Directory<'bytes>)>where + K: Borrow<DirectoryHash>,

source

pub fn values(&self) -> impl Iterator<Item = &Directory<'bytes>>

source

pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Directory<'bytes>>

source§

impl<'bytes> Archive<'bytes>

source

pub fn write<Out>(&self, stream: &mut Out, options: &Options) -> Result<()>where + Out: ?Sized + Write,

Trait Implementations§

source§

impl<'bytes> Clone for Archive<'bytes>

source§

fn clone(&self) -> Archive<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Archive<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Archive<'bytes>

source§

fn default() -> Archive<'bytes>

Returns the “default value” for a type. Read more
source§

impl<'bytes> FromIterator<(Key<'bytes>, Directory<'bytes>)> for Archive<'bytes>

source§

fn from_iter<T>(iter: T) -> Selfwhere + T: IntoIterator<Item = (Key<'bytes>, Directory<'bytes>)>,

Creates a value from an iterator. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this Archive<'bytes>

§

type Item = <&'this BTreeMap<Key<'bytes>, Directory<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this BTreeMap<Key<'bytes>, Directory<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this mut Archive<'bytes>

§

type Item = <&'this mut BTreeMap<Key<'bytes>, Directory<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this mut BTreeMap<Key<'bytes>, Directory<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes> IntoIterator for Archive<'bytes>

§

type Item = <BTreeMap<Key<'bytes>, Directory<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <BTreeMap<Key<'bytes>, Directory<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl Reader<&File> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: &File) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl Reader<&Path> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: &Path) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Borrowed<'bytes>> for Archive<'bytes>

§

type Error = Error

§

type Item = (Archive<'bytes>, Options)

source§

fn read(source: Borrowed<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.
source§

impl<'bytes> Reader<Copied<'bytes>> for Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

fn read(source: Copied<'bytes>) -> Result<Self::Item>

Reads an instance of Self::Item from the given source.

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Archive<'bytes>

§

impl<'bytes> Send for Archive<'bytes>

§

impl<'bytes> Sync for Archive<'bytes>

§

impl<'bytes> Unpin for Archive<'bytes>

§

impl<'bytes> UnwindSafe for Archive<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.ArchiveFlags.html b/ba2/tes4/struct.ArchiveFlags.html new file mode 100644 index 0000000..2125bf2 --- /dev/null +++ b/ba2/tes4/struct.ArchiveFlags.html @@ -0,0 +1,94 @@ +ArchiveFlags in ba2::tes4 - Rust

Struct ba2::tes4::ArchiveFlags

source ·
pub struct ArchiveFlags(/* private fields */);
Expand description

Archive flags can impact the layout of an archive, or how it is read.

+

Implementations§

source§

impl Flags

source

pub const DIRECTORY_STRINGS: Self = _

Includes directory paths within the archive.

+

archive.exe does not let you write archives without this flag set.

+

This includes only the parent path of all files, and not filenames.

+
source

pub const FILE_STRINGS: Self = _

Includes filenames within the archive.

+

archive.exe does not let you write archives without this flag set.

+

This includes only the filename of all files, and not the parent path.

+
source

pub const COMPRESSED: Self = _

Compresses the data within the archive.

+
    +
  • The v103 format uses zlib.
  • +
  • The v104 format uses xmem and zlib.
  • +
  • The v105 format uses lz4.
  • +
+
source

pub const RETAIN_DIRECTORY_NAMES: Self = _

Impacts runtime parsing.

+
source

pub const RETAIN_FILE_NAMES: Self = _

Impacts runtime parsing.

+
source

pub const RETAIN_FILE_NAME_OFFSETS: Self = _

Impacts runtime parsing.

+
source

pub const XBOX_ARCHIVE: Self = _

Writes the archive in the xbox (big-endian) format.

+

This flag affects the sort order of files on disk.

+

Only the crc hash is actually written in big-endian format.

+
source

pub const RETAIN_STRINGS_DURING_STARTUP: Self = _

Impacts runtime parsing.

+
source

pub const EMBEDDED_FILE_NAMES: Self = _

Writes the full (virtual) path of a file next to the data blob.

+

This flag has a different meaning in the v103 format.

+
source

pub const XBOX_COMPRESSED: Self = _

Uses the xmem codec from XNA 4.0 to compress the archive.

+

This flag requires Self::compressed to be set as well.

+

This flag is unused in SSE.

+
source§

impl Flags

source

pub const fn empty() -> Self

Get a flags value with all bits unset.

+
source

pub const fn all() -> Self

Get a flags value with all known bits set.

+
source

pub const fn bits(&self) -> u32

Get the underlying bits value.

+

The returned value is exactly the bits set in this flags value.

+
source

pub const fn from_bits(bits: u32) -> Option<Self>

Convert from a bits value.

+

This method will return None if any unknown bits are set.

+
source

pub const fn from_bits_truncate(bits: u32) -> Self

Convert from a bits value, unsetting any unknown bits.

+
source

pub const fn from_bits_retain(bits: u32) -> Self

Convert from a bits value exactly.

+
source

pub fn from_name(name: &str) -> Option<Self>

Get a flags value with the bits of a flag with the given name set.

+

This method will return None if name is empty or doesn’t +correspond to any named flag.

+
source

pub const fn is_empty(&self) -> bool

Whether all bits in this flags value are unset.

+
source

pub const fn is_all(&self) -> bool

Whether all known bits in this flags value are set.

+
source

pub const fn intersects(&self, other: Self) -> bool

Whether any set bits in a source flags value are also set in a target flags value.

+
source

pub const fn contains(&self, other: Self) -> bool

Whether all set bits in a source flags value are also set in a target flags value.

+
source

pub fn insert(&mut self, other: Self)

The bitwise or (|) of the bits in two flags values.

+
source

pub fn remove(&mut self, other: Self)

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +remove won’t truncate other, but the ! operator will.

+
source

pub fn toggle(&mut self, other: Self)

The bitwise exclusive-or (^) of the bits in two flags values.

+
source

pub fn set(&mut self, other: Self, value: bool)

Call insert when value is true or remove when value is false.

+
source

pub const fn intersection(self, other: Self) -> Self

The bitwise and (&) of the bits in two flags values.

+
source

pub const fn union(self, other: Self) -> Self

The bitwise or (|) of the bits in two flags values.

+
source

pub const fn difference(self, other: Self) -> Self

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +difference won’t truncate other, but the ! operator will.

+
source

pub const fn symmetric_difference(self, other: Self) -> Self

The bitwise exclusive-or (^) of the bits in two flags values.

+
source

pub const fn complement(self) -> Self

The bitwise negation (!) of the bits in a flags value, truncating the result.

+
source§

impl Flags

source

pub const fn iter(&self) -> Iter<Flags>

Yield a set of contained flags values.

+

Each yielded flags value will correspond to a defined named flag. Any unknown bits +will be yielded together as a final flags value.

+
source

pub const fn iter_names(&self) -> IterNames<Flags>

Yield a set of contained named flags values.

+

This method is like iter, except only yields bits in contained named flags. +Any unknown bits, or bits not corresponding to a contained flag will not be yielded.

+
source§

impl Flags

Trait Implementations§

source§

impl Binary for Flags

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl BitAnd for Flags

source§

fn bitand(self, other: Self) -> Self

The bitwise and (&) of the bits in two flags values.

+
§

type Output = Flags

The resulting type after applying the & operator.
source§

impl BitAndAssign for Flags

source§

fn bitand_assign(&mut self, other: Self)

The bitwise and (&) of the bits in two flags values.

+
source§

impl BitOr for Flags

source§

fn bitor(self, other: Flags) -> Self

The bitwise or (|) of the bits in two flags values.

+
§

type Output = Flags

The resulting type after applying the | operator.
source§

impl BitOrAssign for Flags

source§

fn bitor_assign(&mut self, other: Self)

The bitwise or (|) of the bits in two flags values.

+
source§

impl BitXor for Flags

source§

fn bitxor(self, other: Self) -> Self

The bitwise exclusive-or (^) of the bits in two flags values.

+
§

type Output = Flags

The resulting type after applying the ^ operator.
source§

impl BitXorAssign for Flags

source§

fn bitxor_assign(&mut self, other: Self)

The bitwise exclusive-or (^) of the bits in two flags values.

+
source§

impl Clone for Flags

source§

fn clone(&self) -> Flags

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Flags

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Flags

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Extend<Flags> for Flags

source§

fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)

The bitwise or (|) of the bits in each flags value.

+
source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
source§

impl Flags for Flags

source§

const FLAGS: &'static [Flag<Flags>] = _

The set of defined flags.
§

type Bits = u32

The underlying bits type.
source§

fn bits(&self) -> u32

Get the underlying bits value. Read more
source§

fn from_bits_retain(bits: u32) -> Flags

Convert from a bits value exactly.
§

fn empty() -> Self

Get a flags value with all bits unset.
§

fn all() -> Self

Get a flags value with all known bits set.
§

fn from_bits(bits: Self::Bits) -> Option<Self>

Convert from a bits value. Read more
§

fn from_bits_truncate(bits: Self::Bits) -> Self

Convert from a bits value, unsetting any unknown bits.
§

fn from_name(name: &str) -> Option<Self>

Get a flags value with the bits of a flag with the given name set. Read more
§

fn iter(&self) -> Iter<Self>

Yield a set of contained flags values. Read more
§

fn iter_names(&self) -> IterNames<Self>

Yield a set of contained named flags values. Read more
§

fn is_empty(&self) -> bool

Whether all bits in this flags value are unset.
§

fn is_all(&self) -> bool

Whether all known bits in this flags value are set.
§

fn intersects(&self, other: Self) -> boolwhere + Self: Sized,

Whether any set bits in a source flags value are also set in a target flags value.
§

fn contains(&self, other: Self) -> boolwhere + Self: Sized,

Whether all set bits in a source flags value are also set in a target flags value.
§

fn insert(&mut self, other: Self)where + Self: Sized,

The bitwise or (|) of the bits in two flags values.
§

fn remove(&mut self, other: Self)where + Self: Sized,

The intersection of a source flags value with the complement of a target flags value (&!). Read more
§

fn toggle(&mut self, other: Self)where + Self: Sized,

The bitwise exclusive-or (^) of the bits in two flags values.
§

fn set(&mut self, other: Self, value: bool)where + Self: Sized,

Call [Flags::insert] when value is true or [Flags::remove] when value is false.
§

fn intersection(self, other: Self) -> Self

The bitwise and (&) of the bits in two flags values.
§

fn union(self, other: Self) -> Self

The bitwise or (|) of the bits in two flags values.
§

fn difference(self, other: Self) -> Self

The intersection of a source flags value with the complement of a target flags value (&!). Read more
§

fn symmetric_difference(self, other: Self) -> Self

The bitwise exclusive-or (^) of the bits in two flags values.
§

fn complement(self) -> Self

The bitwise negation (!) of the bits in a flags value, truncating the result.
source§

impl FromIterator<Flags> for Flags

source§

fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self

The bitwise or (|) of the bits in each flags value.

+
source§

impl IntoIterator for Flags

§

type Item = Flags

The type of the elements being iterated over.
§

type IntoIter = Iter<Flags>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl LowerHex for Flags

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl Not for Flags

source§

fn not(self) -> Self

The bitwise negation (!) of the bits in a flags value, truncating the result.

+
§

type Output = Flags

The resulting type after applying the ! operator.
source§

impl Octal for Flags

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl PartialEq for Flags

source§

fn eq(&self, other: &Flags) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PublicFlags for Flags

§

type Primitive = u32

The type of the underlying storage.
§

type Internal = InternalBitFlags

The type of the internal field on the generated flags type.
source§

impl Sub for Flags

source§

fn sub(self, other: Self) -> Self

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +difference won’t truncate other, but the ! operator will.

+
§

type Output = Flags

The resulting type after applying the - operator.
source§

impl SubAssign for Flags

source§

fn sub_assign(&mut self, other: Self)

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +difference won’t truncate other, but the ! operator will.

+
source§

impl UpperHex for Flags

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl Copy for Flags

source§

impl Eq for Flags

source§

impl StructuralEq for Flags

source§

impl StructuralPartialEq for Flags

Auto Trait Implementations§

§

impl RefUnwindSafe for Flags

§

impl Send for Flags

§

impl Sync for Flags

§

impl Unpin for Flags

§

impl UnwindSafe for Flags

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.ArchiveKey.html b/ba2/tes4/struct.ArchiveKey.html new file mode 100644 index 0000000..27fc386 --- /dev/null +++ b/ba2/tes4/struct.ArchiveKey.html @@ -0,0 +1,21 @@ +ArchiveKey in ba2::tes4 - Rust

Struct ba2::tes4::ArchiveKey

source ·
pub struct ArchiveKey<'bytes> { /* private fields */ }
Expand description

A key for indexing into the relevant mapping.

+

Implementations§

source§

impl<'bytes> Key<'bytes>

source

pub fn hash(&self) -> &DirectoryHash

source

pub fn name(&self) -> &BStr

Trait Implementations§

source§

impl<'bytes> Borrow<DirectoryHash> for Key<'bytes>

source§

fn borrow(&self) -> &DirectoryHash

Immutably borrows from an owned value. Read more
source§

impl<'bytes> Clone for Key<'bytes>

source§

fn clone(&self) -> Key<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Key<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Key<'bytes>

source§

fn default() -> Key<'bytes>

Returns the “default value” for a type. Read more
source§

impl From<DirectoryHash> for Key<'static>

source§

fn from(value: DirectoryHash) -> Self

Converts to this type from the input type.
source§

impl<T> From<T> for Key<'static>where + T: Into<BString>,

source§

fn from(value: T) -> Self

Converts to this type from the input type.
source§

impl<'bytes> Ord for Key<'bytes>

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'bytes> PartialEq for Key<'bytes>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'bytes> PartialOrd for Key<'bytes>

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'bytes> Eq for Key<'bytes>

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Key<'bytes>

§

impl<'bytes> Send for Key<'bytes>

§

impl<'bytes> Sync for Key<'bytes>

§

impl<'bytes> Unpin for Key<'bytes>

§

impl<'bytes> UnwindSafe for Key<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.ArchiveOptions.html b/ba2/tes4/struct.ArchiveOptions.html new file mode 100644 index 0000000..42ecb95 --- /dev/null +++ b/ba2/tes4/struct.ArchiveOptions.html @@ -0,0 +1,12 @@ +ArchiveOptions in ba2::tes4 - Rust

Struct ba2::tes4::ArchiveOptions

source ·
pub struct ArchiveOptions { /* private fields */ }

Implementations§

source§

impl Options

source

pub fn builder() -> OptionsBuilder

source

pub fn flags(&self) -> Flags

source

pub fn types(&self) -> Types

source

pub fn version(&self) -> Version

Trait Implementations§

source§

impl Clone for Options

source§

fn clone(&self) -> Options

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Options

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Options

source§

fn default() -> Options

Returns the “default value” for a type. Read more
source§

impl From<&Options> for CompressionOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for CompressionOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for ReadOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<&Options> for ReadOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl Copy for Options

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.ArchiveOptionsBuilder.html b/ba2/tes4/struct.ArchiveOptionsBuilder.html new file mode 100644 index 0000000..97d5a35 --- /dev/null +++ b/ba2/tes4/struct.ArchiveOptionsBuilder.html @@ -0,0 +1,12 @@ +ArchiveOptionsBuilder in ba2::tes4 - Rust
pub struct ArchiveOptionsBuilder(/* private fields */);
Expand description

See also ArchiveOptions.

+

Implementations§

source§

impl OptionsBuilder

source

pub fn build(self) -> Options

source

pub fn flags(self, flags: Flags) -> Self

source

pub fn new() -> Self

source

pub fn types(self, types: Types) -> Self

source

pub fn version(self, version: Version) -> Self

Trait Implementations§

source§

impl Debug for OptionsBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for OptionsBuilder

source§

fn default() -> OptionsBuilder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.ArchiveTypes.html b/ba2/tes4/struct.ArchiveTypes.html new file mode 100644 index 0000000..c1965fd --- /dev/null +++ b/ba2/tes4/struct.ArchiveTypes.html @@ -0,0 +1,71 @@ +ArchiveTypes in ba2::tes4 - Rust

Struct ba2::tes4::ArchiveTypes

source ·
pub struct ArchiveTypes(/* private fields */);
Expand description

Specifies file types contained within an archive.

+

It’s not apparent if the game actually uses these flags for anything.

+

Implementations§

source§

impl Types

source

pub const MESHES: Self = _

source

pub const TEXTURES: Self = _

source

pub const MENUS: Self = _

source

pub const SOUNDS: Self = _

source

pub const VOICES: Self = _

source

pub const SHADERS: Self = _

source

pub const TREES: Self = _

source

pub const FONTS: Self = _

source

pub const MISC: Self = _

source§

impl Types

source

pub const fn empty() -> Self

Get a flags value with all bits unset.

+
source

pub const fn all() -> Self

Get a flags value with all known bits set.

+
source

pub const fn bits(&self) -> u16

Get the underlying bits value.

+

The returned value is exactly the bits set in this flags value.

+
source

pub const fn from_bits(bits: u16) -> Option<Self>

Convert from a bits value.

+

This method will return None if any unknown bits are set.

+
source

pub const fn from_bits_truncate(bits: u16) -> Self

Convert from a bits value, unsetting any unknown bits.

+
source

pub const fn from_bits_retain(bits: u16) -> Self

Convert from a bits value exactly.

+
source

pub fn from_name(name: &str) -> Option<Self>

Get a flags value with the bits of a flag with the given name set.

+

This method will return None if name is empty or doesn’t +correspond to any named flag.

+
source

pub const fn is_empty(&self) -> bool

Whether all bits in this flags value are unset.

+
source

pub const fn is_all(&self) -> bool

Whether all known bits in this flags value are set.

+
source

pub const fn intersects(&self, other: Self) -> bool

Whether any set bits in a source flags value are also set in a target flags value.

+
source

pub const fn contains(&self, other: Self) -> bool

Whether all set bits in a source flags value are also set in a target flags value.

+
source

pub fn insert(&mut self, other: Self)

The bitwise or (|) of the bits in two flags values.

+
source

pub fn remove(&mut self, other: Self)

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +remove won’t truncate other, but the ! operator will.

+
source

pub fn toggle(&mut self, other: Self)

The bitwise exclusive-or (^) of the bits in two flags values.

+
source

pub fn set(&mut self, other: Self, value: bool)

Call insert when value is true or remove when value is false.

+
source

pub const fn intersection(self, other: Self) -> Self

The bitwise and (&) of the bits in two flags values.

+
source

pub const fn union(self, other: Self) -> Self

The bitwise or (|) of the bits in two flags values.

+
source

pub const fn difference(self, other: Self) -> Self

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +difference won’t truncate other, but the ! operator will.

+
source

pub const fn symmetric_difference(self, other: Self) -> Self

The bitwise exclusive-or (^) of the bits in two flags values.

+
source

pub const fn complement(self) -> Self

The bitwise negation (!) of the bits in a flags value, truncating the result.

+
source§

impl Types

source

pub const fn iter(&self) -> Iter<Types>

Yield a set of contained flags values.

+

Each yielded flags value will correspond to a defined named flag. Any unknown bits +will be yielded together as a final flags value.

+
source

pub const fn iter_names(&self) -> IterNames<Types>

Yield a set of contained named flags values.

+

This method is like iter, except only yields bits in contained named flags. +Any unknown bits, or bits not corresponding to a contained flag will not be yielded.

+
source§

impl Types

source

pub fn meshes(&self) -> bool

source

pub fn textures(&self) -> bool

source

pub fn menus(&self) -> bool

source

pub fn sounds(&self) -> bool

source

pub fn voices(&self) -> bool

source

pub fn shaders(&self) -> bool

source

pub fn trees(&self) -> bool

source

pub fn fonts(&self) -> bool

source

pub fn misc(&self) -> bool

Trait Implementations§

source§

impl Binary for Types

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl BitAnd for Types

source§

fn bitand(self, other: Self) -> Self

The bitwise and (&) of the bits in two flags values.

+
§

type Output = Types

The resulting type after applying the & operator.
source§

impl BitAndAssign for Types

source§

fn bitand_assign(&mut self, other: Self)

The bitwise and (&) of the bits in two flags values.

+
source§

impl BitOr for Types

source§

fn bitor(self, other: Types) -> Self

The bitwise or (|) of the bits in two flags values.

+
§

type Output = Types

The resulting type after applying the | operator.
source§

impl BitOrAssign for Types

source§

fn bitor_assign(&mut self, other: Self)

The bitwise or (|) of the bits in two flags values.

+
source§

impl BitXor for Types

source§

fn bitxor(self, other: Self) -> Self

The bitwise exclusive-or (^) of the bits in two flags values.

+
§

type Output = Types

The resulting type after applying the ^ operator.
source§

impl BitXorAssign for Types

source§

fn bitxor_assign(&mut self, other: Self)

The bitwise exclusive-or (^) of the bits in two flags values.

+
source§

impl Clone for Types

source§

fn clone(&self) -> Types

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Types

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Types

source§

fn default() -> Types

Returns the “default value” for a type. Read more
source§

impl Extend<Types> for Types

source§

fn extend<T: IntoIterator<Item = Self>>(&mut self, iterator: T)

The bitwise or (|) of the bits in each flags value.

+
source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
source§

impl Flags for Types

source§

const FLAGS: &'static [Flag<Types>] = _

The set of defined flags.
§

type Bits = u16

The underlying bits type.
source§

fn bits(&self) -> u16

Get the underlying bits value. Read more
source§

fn from_bits_retain(bits: u16) -> Types

Convert from a bits value exactly.
§

fn empty() -> Self

Get a flags value with all bits unset.
§

fn all() -> Self

Get a flags value with all known bits set.
§

fn from_bits(bits: Self::Bits) -> Option<Self>

Convert from a bits value. Read more
§

fn from_bits_truncate(bits: Self::Bits) -> Self

Convert from a bits value, unsetting any unknown bits.
§

fn from_name(name: &str) -> Option<Self>

Get a flags value with the bits of a flag with the given name set. Read more
§

fn iter(&self) -> Iter<Self>

Yield a set of contained flags values. Read more
§

fn iter_names(&self) -> IterNames<Self>

Yield a set of contained named flags values. Read more
§

fn is_empty(&self) -> bool

Whether all bits in this flags value are unset.
§

fn is_all(&self) -> bool

Whether all known bits in this flags value are set.
§

fn intersects(&self, other: Self) -> boolwhere + Self: Sized,

Whether any set bits in a source flags value are also set in a target flags value.
§

fn contains(&self, other: Self) -> boolwhere + Self: Sized,

Whether all set bits in a source flags value are also set in a target flags value.
§

fn insert(&mut self, other: Self)where + Self: Sized,

The bitwise or (|) of the bits in two flags values.
§

fn remove(&mut self, other: Self)where + Self: Sized,

The intersection of a source flags value with the complement of a target flags value (&!). Read more
§

fn toggle(&mut self, other: Self)where + Self: Sized,

The bitwise exclusive-or (^) of the bits in two flags values.
§

fn set(&mut self, other: Self, value: bool)where + Self: Sized,

Call [Flags::insert] when value is true or [Flags::remove] when value is false.
§

fn intersection(self, other: Self) -> Self

The bitwise and (&) of the bits in two flags values.
§

fn union(self, other: Self) -> Self

The bitwise or (|) of the bits in two flags values.
§

fn difference(self, other: Self) -> Self

The intersection of a source flags value with the complement of a target flags value (&!). Read more
§

fn symmetric_difference(self, other: Self) -> Self

The bitwise exclusive-or (^) of the bits in two flags values.
§

fn complement(self) -> Self

The bitwise negation (!) of the bits in a flags value, truncating the result.
source§

impl FromIterator<Types> for Types

source§

fn from_iter<T: IntoIterator<Item = Self>>(iterator: T) -> Self

The bitwise or (|) of the bits in each flags value.

+
source§

impl IntoIterator for Types

§

type Item = Types

The type of the elements being iterated over.
§

type IntoIter = Iter<Types>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl LowerHex for Types

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl Not for Types

source§

fn not(self) -> Self

The bitwise negation (!) of the bits in a flags value, truncating the result.

+
§

type Output = Types

The resulting type after applying the ! operator.
source§

impl Octal for Types

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl PartialEq for Types

source§

fn eq(&self, other: &Types) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PublicFlags for Types

§

type Primitive = u16

The type of the underlying storage.
§

type Internal = InternalBitFlags

The type of the internal field on the generated flags type.
source§

impl Sub for Types

source§

fn sub(self, other: Self) -> Self

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +difference won’t truncate other, but the ! operator will.

+
§

type Output = Types

The resulting type after applying the - operator.
source§

impl SubAssign for Types

source§

fn sub_assign(&mut self, other: Self)

The intersection of a source flags value with the complement of a target flags value (&!).

+

This method is not equivalent to self & !other when other has unknown bits set. +difference won’t truncate other, but the ! operator will.

+
source§

impl UpperHex for Types

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter.
source§

impl Copy for Types

source§

impl Eq for Types

source§

impl StructuralEq for Types

source§

impl StructuralPartialEq for Types

Auto Trait Implementations§

§

impl RefUnwindSafe for Types

§

impl Send for Types

§

impl Sync for Types

§

impl Unpin for Types

§

impl UnwindSafe for Types

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.Directory.html b/ba2/tes4/struct.Directory.html new file mode 100644 index 0000000..737ed0f --- /dev/null +++ b/ba2/tes4/struct.Directory.html @@ -0,0 +1,25 @@ +Directory in ba2::tes4 - Rust

Struct ba2::tes4::Directory

source ·
pub struct Directory<'bytes> { /* private fields */ }
Expand description

Represents a directory within the TES4 virtual filesystem.

+

Implementations§

source§

impl<'bytes> Directory<'bytes>

source

pub fn clear(&mut self)

source

pub fn get<K>(&self, key: &K) -> Option<&File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn get_key_value<K>(&self, key: &K) -> Option<(&Key<'bytes>, &File<'bytes>)>where + K: Borrow<FileHash>,

source

pub fn get_mut<K>(&mut self, key: &K) -> Option<&mut File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn insert<K>(&mut self, key: K, value: File<'bytes>) -> Option<File<'bytes>>where + K: Into<Key<'bytes>>,

source

pub fn is_empty(&self) -> bool

source

pub fn iter(&self) -> impl Iterator<Item = (&Key<'bytes>, &File<'bytes>)>

source

pub fn iter_mut( + &mut self +) -> impl Iterator<Item = (&Key<'bytes>, &mut File<'bytes>)>

source

pub fn keys(&self) -> impl Iterator<Item = &Key<'bytes>>

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source

pub fn remove<K>(&mut self, key: &K) -> Option<File<'bytes>>where + K: Borrow<FileHash>,

source

pub fn remove_entry<K>( + &mut self, + key: &K +) -> Option<(Key<'bytes>, File<'bytes>)>where + K: Borrow<FileHash>,

source

pub fn values(&self) -> impl Iterator<Item = &File<'bytes>>

source

pub fn values_mut(&mut self) -> impl Iterator<Item = &mut File<'bytes>>

Trait Implementations§

source§

impl<'bytes> Clone for Directory<'bytes>

source§

fn clone(&self) -> Directory<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Directory<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Directory<'bytes>

source§

fn default() -> Directory<'bytes>

Returns the “default value” for a type. Read more
source§

impl<'bytes> FromIterator<(Key<'bytes>, File<'bytes>)> for Directory<'bytes>

source§

fn from_iter<T>(iter: T) -> Selfwhere + T: IntoIterator<Item = (Key<'bytes>, File<'bytes>)>,

Creates a value from an iterator. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this Directory<'bytes>

§

type Item = <&'this BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes, 'this> IntoIterator for &'this mut Directory<'bytes>

§

type Item = <&'this mut BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <&'this mut BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<'bytes> IntoIterator for Directory<'bytes>

§

type Item = <BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::Item

The type of the elements being iterated over.
§

type IntoIter = <BTreeMap<Key<'bytes>, File<'bytes>> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Directory<'bytes>

§

impl<'bytes> Send for Directory<'bytes>

§

impl<'bytes> Sync for Directory<'bytes>

§

impl<'bytes> Unpin for Directory<'bytes>

§

impl<'bytes> UnwindSafe for Directory<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.DirectoryHash.html b/ba2/tes4/struct.DirectoryHash.html new file mode 100644 index 0000000..8a81d61 --- /dev/null +++ b/ba2/tes4/struct.DirectoryHash.html @@ -0,0 +1,28 @@ +DirectoryHash in ba2::tes4 - Rust

Struct ba2::tes4::DirectoryHash

source ·
pub struct DirectoryHash(/* private fields */);
Expand description

See also Hash.

+

Implementations§

source§

impl DirectoryHash

source

pub fn new() -> Self

Methods from Deref<Target = Hash>§

source

pub fn numeric(&self) -> u64

Trait Implementations§

source§

impl AsMut<Hash> for DirectoryHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for DirectoryHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<'bytes> Borrow<DirectoryHash> for Key<'bytes>

source§

fn borrow(&self) -> &DirectoryHash

Immutably borrows from an owned value. Read more
source§

impl Borrow<Hash> for DirectoryHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for DirectoryHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl Clone for DirectoryHash

source§

fn clone(&self) -> DirectoryHash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for DirectoryHash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for DirectoryHash

source§

fn default() -> DirectoryHash

Returns the “default value” for a type. Read more
source§

impl Deref for DirectoryHash

§

type Target = Hash

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for DirectoryHash

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl From<DirectoryHash> for Hash

source§

fn from(value: DirectoryHash) -> Self

Converts to this type from the input type.
source§

impl From<DirectoryHash> for Key<'static>

source§

fn from(value: DirectoryHash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for DirectoryHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl Ord for DirectoryHash

source§

fn cmp(&self, other: &DirectoryHash) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<DirectoryHash> for Hash

source§

fn eq(&self, other: &DirectoryHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for DirectoryHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for DirectoryHash

source§

fn eq(&self, other: &DirectoryHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<DirectoryHash> for Hash

source§

fn partial_cmp(&self, other: &DirectoryHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for DirectoryHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for DirectoryHash

source§

fn partial_cmp(&self, other: &DirectoryHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for DirectoryHash

source§

impl Eq for DirectoryHash

source§

impl StructuralEq for DirectoryHash

source§

impl StructuralPartialEq for DirectoryHash

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.DirectoryKey.html b/ba2/tes4/struct.DirectoryKey.html new file mode 100644 index 0000000..22f231a --- /dev/null +++ b/ba2/tes4/struct.DirectoryKey.html @@ -0,0 +1,21 @@ +DirectoryKey in ba2::tes4 - Rust

Struct ba2::tes4::DirectoryKey

source ·
pub struct DirectoryKey<'bytes> { /* private fields */ }
Expand description

A key for indexing into the relevant mapping.

+

Implementations§

source§

impl<'bytes> Key<'bytes>

source

pub fn hash(&self) -> &FileHash

source

pub fn name(&self) -> &BStr

Trait Implementations§

source§

impl<'bytes> Borrow<FileHash> for Key<'bytes>

source§

fn borrow(&self) -> &FileHash

Immutably borrows from an owned value. Read more
source§

impl<'bytes> Clone for Key<'bytes>

source§

fn clone(&self) -> Key<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> Debug for Key<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for Key<'bytes>

source§

fn default() -> Key<'bytes>

Returns the “default value” for a type. Read more
source§

impl From<FileHash> for Key<'static>

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl<T> From<T> for Key<'static>where + T: Into<BString>,

source§

fn from(value: T) -> Self

Converts to this type from the input type.
source§

impl<'bytes> Ord for Key<'bytes>

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'bytes> PartialEq for Key<'bytes>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'bytes> PartialOrd for Key<'bytes>

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'bytes> Eq for Key<'bytes>

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for Key<'bytes>

§

impl<'bytes> Send for Key<'bytes>

§

impl<'bytes> Sync for Key<'bytes>

§

impl<'bytes> Unpin for Key<'bytes>

§

impl<'bytes> UnwindSafe for Key<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.File.html b/ba2/tes4/struct.File.html new file mode 100644 index 0000000..b4072b3 --- /dev/null +++ b/ba2/tes4/struct.File.html @@ -0,0 +1,26 @@ +File in ba2::tes4 - Rust

Struct ba2::tes4::File

source ·
pub struct File<'bytes> { /* private fields */ }
Expand description

Represents a file within the TES4 virtual filesystem.

+

Implementations§

source§

impl<'bytes> File<'bytes>

source

pub fn as_bytes(&self) -> &[u8]

source

pub fn as_ptr(&self) -> *const u8

source

pub fn into_owned(self) -> File<'static>

source

pub fn is_empty(&self) -> bool

source

pub fn len(&self) -> usize

source

pub fn new() -> Self

source§

impl<'bytes> File<'bytes>

source

pub fn compress(&self, options: &CompressionOptions) -> Result<File<'static>>

source

pub fn decompress(&self, options: &CompressionOptions) -> Result<File<'static>>

source

pub fn decompressed_len(&self) -> Option<usize>

source

pub fn is_compressed(&self) -> bool

source

pub fn is_decompressed(&self) -> bool

source

pub fn write<Out>( + &self, + stream: &mut Out, + options: &CompressionOptions +) -> Result<()>where + Out: ?Sized + Write,

source§

impl<'bytes> File<'bytes>

source

pub fn compress_into( + &self, + out: &mut Vec<u8>, + options: &CompressionOptions +) -> Result<()>

source

pub fn decompress_into( + &self, + out: &mut Vec<u8>, + options: &CompressionOptions +) -> Result<()>

Trait Implementations§

source§

impl<'bytes> Clone for File<'bytes>

source§

fn clone(&self) -> File<'bytes>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'bytes> CompressableFrom<&'bytes [u8]> for File<'bytes>

source§

fn from_compressed(value: &'bytes [u8], decompressed_len: usize) -> Self

Makes a compressed instance of Self using the given data.
source§

fn from_decompressed(value: &'bytes [u8]) -> Self

Makes a decompressed instance of Self using the given data.
source§

impl<'bytes, const N: usize> CompressableFrom<&'bytes [u8; N]> for File<'bytes>

source§

fn from_compressed(value: &'bytes [u8; N], decompressed_len: usize) -> Self

Makes a compressed instance of Self using the given data.
source§

fn from_decompressed(value: &'bytes [u8; N]) -> Self

Makes a decompressed instance of Self using the given data.
source§

impl CompressableFrom<Box<[u8]>> for File<'static>

source§

fn from_compressed(value: Box<[u8]>, decompressed_len: usize) -> Self

Makes a compressed instance of Self using the given data.
source§

fn from_decompressed(value: Box<[u8]>) -> Self

Makes a decompressed instance of Self using the given data.
source§

impl<'bytes> Debug for File<'bytes>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'bytes> Default for File<'bytes>

source§

fn default() -> File<'bytes>

Returns the “default value” for a type. Read more
source§

impl ReaderWithOptions<&File> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: &File, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl ReaderWithOptions<&Path> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: &Path, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl<'bytes> ReaderWithOptions<Borrowed<'bytes>> for File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

§

type Options = ReadOptions

source§

fn read(source: Borrowed<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.
source§

impl<'bytes> ReaderWithOptions<Copied<'bytes>> for File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

fn read(source: Copied<'bytes>, options: &Self::Options) -> Result<Self::Item>

Reads an instance of Self::Item from the given source, using the given options.

Auto Trait Implementations§

§

impl<'bytes> RefUnwindSafe for File<'bytes>

§

impl<'bytes> Send for File<'bytes>

§

impl<'bytes> Sync for File<'bytes>

§

impl<'bytes> Unpin for File<'bytes>

§

impl<'bytes> UnwindSafe for File<'bytes>

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.FileCompressionOptions.html b/ba2/tes4/struct.FileCompressionOptions.html new file mode 100644 index 0000000..436dcc4 --- /dev/null +++ b/ba2/tes4/struct.FileCompressionOptions.html @@ -0,0 +1,30 @@ +FileCompressionOptions in ba2::tes4 - Rust
pub struct FileCompressionOptions { /* private fields */ }
Expand description

Common parameters to configure how files are compressed/decompressed.

+ +
use ba2::tes4::{FileCompressionOptions, Version};
+
+// Configure for TES:IV
+let _ = FileCompressionOptions::builder()
+    .version(Version::TES4)
+    .build();
+
+// Configure for F3/FNV/TES:V
+let _ = FileCompressionOptions::builder()
+    .version(Version::FO3)
+    .build();
+
+// Configure for SSE
+let _ = FileCompressionOptions::builder()
+    .version(Version::SSE)
+    .build();
+

Implementations§

Trait Implementations§

source§

impl Clone for CompressionOptions

source§

fn clone(&self) -> CompressionOptions

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CompressionOptions

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionOptions

source§

fn default() -> CompressionOptions

Returns the “default value” for a type. Read more
source§

impl From<&Options> for CompressionOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl Copy for CompressionOptions

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.FileCompressionOptionsBuilder.html b/ba2/tes4/struct.FileCompressionOptionsBuilder.html new file mode 100644 index 0000000..efbad31 --- /dev/null +++ b/ba2/tes4/struct.FileCompressionOptionsBuilder.html @@ -0,0 +1,12 @@ +FileCompressionOptionsBuilder in ba2::tes4 - Rust
pub struct FileCompressionOptionsBuilder(/* private fields */);
Expand description

Implementations§

source§

impl CompressionOptionsBuilder

source

pub fn build(self) -> CompressionOptions

source

pub fn compression_codec(self, compression_codec: CompressionCodec) -> Self

source

pub fn new() -> Self

source

pub fn version(self, version: Version) -> Self

Trait Implementations§

source§

impl Debug for CompressionOptionsBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for CompressionOptionsBuilder

source§

fn default() -> CompressionOptionsBuilder

Returns the “default value” for a type. Read more
source§

impl From<&Options> for CompressionOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for CompressionOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.FileHash.html b/ba2/tes4/struct.FileHash.html new file mode 100644 index 0000000..627fd5c --- /dev/null +++ b/ba2/tes4/struct.FileHash.html @@ -0,0 +1,28 @@ +FileHash in ba2::tes4 - Rust

Struct ba2::tes4::FileHash

source ·
pub struct FileHash(/* private fields */);
Expand description

See also Hash.

+

Implementations§

source§

impl FileHash

source

pub fn new() -> Self

Methods from Deref<Target = Hash>§

source

pub fn numeric(&self) -> u64

Trait Implementations§

source§

impl AsMut<Hash> for FileHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for FileHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<'bytes> Borrow<FileHash> for Key<'bytes>

source§

fn borrow(&self) -> &FileHash

Immutably borrows from an owned value. Read more
source§

impl Borrow<Hash> for FileHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for FileHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl Clone for FileHash

source§

fn clone(&self) -> FileHash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for FileHash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for FileHash

source§

fn default() -> FileHash

Returns the “default value” for a type. Read more
source§

impl Deref for FileHash

§

type Target = Hash

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for FileHash

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl From<FileHash> for Hash

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<FileHash> for Key<'static>

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for FileHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl Ord for FileHash

source§

fn cmp(&self, other: &FileHash) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<FileHash> for Hash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for FileHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for FileHash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<FileHash> for Hash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for FileHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for FileHash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for FileHash

source§

impl Eq for FileHash

source§

impl StructuralEq for FileHash

source§

impl StructuralPartialEq for FileHash

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.FileReadOptions.html b/ba2/tes4/struct.FileReadOptions.html new file mode 100644 index 0000000..2d76b39 --- /dev/null +++ b/ba2/tes4/struct.FileReadOptions.html @@ -0,0 +1,36 @@ +FileReadOptions in ba2::tes4 - Rust

Struct ba2::tes4::FileReadOptions

source ·
pub struct FileReadOptions { /* private fields */ }
Expand description

Common parameters to configure how files are read.

+ +
use ba2::{
+    tes4::{FileReadOptions, Version},
+    CompressionResult,
+};
+
+// Read and compress a file for TES:IV
+let _ = FileReadOptions::builder()
+    .version(Version::TES4)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+
+// Read and compress a file for F3/FNV/TES:V
+let _ = FileReadOptions::builder()
+    .version(Version::FO3)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+
+// Read and compress a file for SSE
+let _ = FileReadOptions::builder()
+    .version(Version::SSE)
+    .compression_result(CompressionResult::Compressed)
+    .build();
+

Implementations§

Trait Implementations§

source§

impl Clone for ReadOptions

source§

fn clone(&self) -> ReadOptions

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ReadOptions

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ReadOptions

source§

fn default() -> ReadOptions

Returns the “default value” for a type. Read more
source§

impl From<&Options> for ReadOptions

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptions

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl Copy for ReadOptions

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.FileReadOptionsBuilder.html b/ba2/tes4/struct.FileReadOptionsBuilder.html new file mode 100644 index 0000000..a8bd829 --- /dev/null +++ b/ba2/tes4/struct.FileReadOptionsBuilder.html @@ -0,0 +1,12 @@ +FileReadOptionsBuilder in ba2::tes4 - Rust
pub struct FileReadOptionsBuilder(/* private fields */);
Expand description

See also FileReadOptions.

+

Implementations§

source§

impl ReadOptionsBuilder

source

pub fn build(self) -> ReadOptions

source

pub fn compression_codec(self, compression_codec: CompressionCodec) -> Self

source

pub fn compression_result(self, compression_result: CompressionResult) -> Self

source

pub fn new() -> Self

source

pub fn version(self, version: Version) -> Self

Trait Implementations§

source§

impl Debug for ReadOptionsBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ReadOptionsBuilder

source§

fn default() -> ReadOptionsBuilder

Returns the “default value” for a type. Read more
source§

impl From<&Options> for ReadOptionsBuilder

source§

fn from(value: &ArchiveOptions) -> Self

Converts to this type from the input type.
source§

impl From<Options> for ReadOptionsBuilder

source§

fn from(value: ArchiveOptions) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/struct.Hash.html b/ba2/tes4/struct.Hash.html new file mode 100644 index 0000000..22f0736 --- /dev/null +++ b/ba2/tes4/struct.Hash.html @@ -0,0 +1,46 @@ +Hash in ba2::tes4 - Rust

Struct ba2::tes4::Hash

source ·
#[repr(C)]
pub struct Hash { + pub last: u8, + pub last2: u8, + pub length: u8, + pub first: u8, + pub crc: u32, +}
Expand description

The underlying hash object used to uniquely identify objects within the archive.

+

Fields§

§last: u8

The last character of the path (directory) or stem (file).

+
§last2: u8

The second to last character of the path (directory) or stem (file).

+
§length: u8

The length of the path (directory) or stem (file).

+
§first: u8

The first character of the path (directory) or stem (file).

+
§crc: u32

Implementations§

source§

impl Hash

source

pub fn new() -> Self

source

pub fn numeric(&self) -> u64

Trait Implementations§

source§

impl AsMut<Hash> for DirectoryHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsMut<Hash> for FileHash

source§

fn as_mut(&mut self) -> &mut Hash

Converts this type into a mutable reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for DirectoryHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl AsRef<Hash> for FileHash

source§

fn as_ref(&self) -> &Hash

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Borrow<Hash> for DirectoryHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl Borrow<Hash> for FileHash

source§

fn borrow(&self) -> &Hash

Immutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for DirectoryHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl BorrowMut<Hash> for FileHash

source§

fn borrow_mut(&mut self) -> &mut Hash

Mutably borrows from an owned value. Read more
source§

impl Clone for Hash

source§

fn clone(&self) -> Hash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Hash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Hash

source§

fn default() -> Hash

Returns the “default value” for a type. Read more
source§

impl From<DirectoryHash> for Hash

source§

fn from(value: DirectoryHash) -> Self

Converts to this type from the input type.
source§

impl From<FileHash> for Hash

source§

fn from(value: FileHash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for DirectoryHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl From<Hash> for FileHash

source§

fn from(value: Hash) -> Self

Converts to this type from the input type.
source§

impl Ord for Hash

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<DirectoryHash> for Hash

source§

fn eq(&self, other: &DirectoryHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<FileHash> for Hash

source§

fn eq(&self, other: &FileHash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for DirectoryHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Hash> for FileHash

source§

fn eq(&self, other: &Hash) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Hash

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<DirectoryHash> for Hash

source§

fn partial_cmp(&self, other: &DirectoryHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<FileHash> for Hash

source§

fn partial_cmp(&self, other: &FileHash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for DirectoryHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Hash> for FileHash

source§

fn partial_cmp(&self, other: &Hash) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for Hash

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Hash

source§

impl Eq for Hash

Auto Trait Implementations§

§

impl RefUnwindSafe for Hash

§

impl Send for Hash

§

impl Sync for Hash

§

impl Unpin for Hash

§

impl UnwindSafe for Hash

Blanket Implementations§

source§

impl<T> Any for Twhere + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
source§

impl<T, U> Into<U> for Twhere + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for Twhere + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

fn clone_into(&self, target: &mut T)

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

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere + U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
\ No newline at end of file diff --git a/ba2/tes4/type.Result.html b/ba2/tes4/type.Result.html new file mode 100644 index 0000000..b55a941 --- /dev/null +++ b/ba2/tes4/type.Result.html @@ -0,0 +1,6 @@ +Result in ba2::tes4 - Rust

Type Alias ba2::tes4::Result

source ·
pub type Result<T> = Result<T, Error>;

Aliased Type§

enum Result<T> {
+    Ok(T),
+    Err(Error),
+}

Variants§

§1.0.0

Ok(T)

Contains the success value

+
§1.0.0

Err(Error)

Contains the error value

+
\ No newline at end of file diff --git a/ba2/trait.ByteSlice.html b/ba2/trait.ByteSlice.html new file mode 100644 index 0000000..835a1d2 --- /dev/null +++ b/ba2/trait.ByteSlice.html @@ -0,0 +1,1883 @@ +ByteSlice in ba2 - Rust

Trait ba2::ByteSlice

pub trait ByteSlice: Sealed {
+
Show 76 methods // Provided methods + fn as_bstr(&self) -> &BStr { ... } + fn as_bstr_mut(&mut self) -> &mut BStr { ... } + fn from_os_str(os_str: &OsStr) -> Option<&[u8]> { ... } + fn from_path(path: &Path) -> Option<&[u8]> { ... } + fn to_str(&self) -> Result<&str, Utf8Error> { ... } + unsafe fn to_str_unchecked(&self) -> &str { ... } + fn to_str_lossy(&self) -> Cow<'_, str> { ... } + fn to_str_lossy_into(&self, dest: &mut String) { ... } + fn to_os_str(&self) -> Result<&OsStr, Utf8Error> { ... } + fn to_os_str_lossy(&self) -> Cow<'_, OsStr> { ... } + fn to_path(&self) -> Result<&Path, Utf8Error> { ... } + fn to_path_lossy(&self) -> Cow<'_, Path> { ... } + fn repeatn(&self, n: usize) -> Vec<u8> { ... } + fn contains_str<B>(&self, needle: B) -> bool + where B: AsRef<[u8]> { ... } + fn starts_with_str<B>(&self, prefix: B) -> bool + where B: AsRef<[u8]> { ... } + fn ends_with_str<B>(&self, suffix: B) -> bool + where B: AsRef<[u8]> { ... } + fn find<B>(&self, needle: B) -> Option<usize> + where B: AsRef<[u8]> { ... } + fn rfind<B>(&self, needle: B) -> Option<usize> + where B: AsRef<[u8]> { ... } + fn find_iter<B, 'h, 'n>(&'h self, needle: &'n B) -> Find<'h, 'n> + where B: AsRef<[u8]> + ?Sized { ... } + fn rfind_iter<B, 'h, 'n>(&'h self, needle: &'n B) -> FindReverse<'h, 'n> + where B: AsRef<[u8]> + ?Sized { ... } + fn find_byte(&self, byte: u8) -> Option<usize> { ... } + fn rfind_byte(&self, byte: u8) -> Option<usize> { ... } + fn find_char(&self, ch: char) -> Option<usize> { ... } + fn rfind_char(&self, ch: char) -> Option<usize> { ... } + fn find_byteset<B>(&self, byteset: B) -> Option<usize> + where B: AsRef<[u8]> { ... } + fn find_not_byteset<B>(&self, byteset: B) -> Option<usize> + where B: AsRef<[u8]> { ... } + fn rfind_byteset<B>(&self, byteset: B) -> Option<usize> + where B: AsRef<[u8]> { ... } + fn rfind_not_byteset<B>(&self, byteset: B) -> Option<usize> + where B: AsRef<[u8]> { ... } + fn fields(&self) -> Fields<'_> { ... } + fn fields_with<F>(&self, f: F) -> FieldsWith<'_, F> + where F: FnMut(char) -> bool { ... } + fn split_str<B, 'h, 's>(&'h self, splitter: &'s B) -> Split<'h, 's> + where B: AsRef<[u8]> + ?Sized { ... } + fn rsplit_str<B, 'h, 's>(&'h self, splitter: &'s B) -> SplitReverse<'h, 's> + where B: AsRef<[u8]> + ?Sized { ... } + fn split_once_str<B, 'a>( + &'a self, + splitter: &B + ) -> Option<(&'a [u8], &'a [u8])> + where B: AsRef<[u8]> + ?Sized { ... } + fn rsplit_once_str<B, 'a>( + &'a self, + splitter: &B + ) -> Option<(&'a [u8], &'a [u8])> + where B: AsRef<[u8]> + ?Sized { ... } + fn splitn_str<B, 'h, 's>( + &'h self, + limit: usize, + splitter: &'s B + ) -> SplitN<'h, 's> + where B: AsRef<[u8]> + ?Sized { ... } + fn rsplitn_str<B, 'h, 's>( + &'h self, + limit: usize, + splitter: &'s B + ) -> SplitNReverse<'h, 's> + where B: AsRef<[u8]> + ?Sized { ... } + fn replace<N, R>(&self, needle: N, replacement: R) -> Vec<u8> + where N: AsRef<[u8]>, + R: AsRef<[u8]> { ... } + fn replacen<N, R>(&self, needle: N, replacement: R, limit: usize) -> Vec<u8> + where N: AsRef<[u8]>, + R: AsRef<[u8]> { ... } + fn replace_into<N, R>(&self, needle: N, replacement: R, dest: &mut Vec<u8>) + where N: AsRef<[u8]>, + R: AsRef<[u8]> { ... } + fn replacen_into<N, R>( + &self, + needle: N, + replacement: R, + limit: usize, + dest: &mut Vec<u8> + ) + where N: AsRef<[u8]>, + R: AsRef<[u8]> { ... } + fn bytes(&self) -> Bytes<'_> { ... } + fn chars(&self) -> Chars<'_> { ... } + fn char_indices(&self) -> CharIndices<'_> { ... } + fn utf8_chunks(&self) -> Utf8Chunks<'_> { ... } + fn graphemes(&self) -> Graphemes<'_> { ... } + fn grapheme_indices(&self) -> GraphemeIndices<'_> { ... } + fn words(&self) -> Words<'_> { ... } + fn word_indices(&self) -> WordIndices<'_> { ... } + fn words_with_breaks(&self) -> WordsWithBreaks<'_> { ... } + fn words_with_break_indices(&self) -> WordsWithBreakIndices<'_> { ... } + fn sentences(&self) -> Sentences<'_> { ... } + fn sentence_indices(&self) -> SentenceIndices<'_> { ... } + fn lines(&self) -> Lines<'_> { ... } + fn lines_with_terminator(&self) -> LinesWithTerminator<'_> { ... } + fn trim(&self) -> &[u8] { ... } + fn trim_start(&self) -> &[u8] { ... } + fn trim_end(&self) -> &[u8] { ... } + fn trim_with<F>(&self, trim: F) -> &[u8] + where F: FnMut(char) -> bool { ... } + fn trim_start_with<F>(&self, trim: F) -> &[u8] + where F: FnMut(char) -> bool { ... } + fn trim_end_with<F>(&self, trim: F) -> &[u8] + where F: FnMut(char) -> bool { ... } + fn to_lowercase(&self) -> Vec<u8> { ... } + fn to_lowercase_into(&self, buf: &mut Vec<u8>) { ... } + fn to_ascii_lowercase(&self) -> Vec<u8> { ... } + fn make_ascii_lowercase(&mut self) { ... } + fn to_uppercase(&self) -> Vec<u8> { ... } + fn to_uppercase_into(&self, buf: &mut Vec<u8>) { ... } + fn to_ascii_uppercase(&self) -> Vec<u8> { ... } + fn make_ascii_uppercase(&mut self) { ... } + fn escape_bytes(&self) -> EscapeBytes<'_> { ... } + fn reverse_bytes(&mut self) { ... } + fn reverse_chars(&mut self) { ... } + fn reverse_graphemes(&mut self) { ... } + fn is_ascii(&self) -> bool { ... } + fn is_utf8(&self) -> bool { ... } + fn last_byte(&self) -> Option<u8> { ... } + fn find_non_ascii_byte(&self) -> Option<usize> { ... } +
}
Expand description

A trait that extends &[u8] with string oriented methods.

+

This trait is sealed and cannot be implemented outside of bstr.

+

Provided Methods§

fn as_bstr(&self) -> &BStr

Return this byte slice as a &BStr.

+

Use &BStr is useful because of its fmt::Debug representation +and various other trait implementations (such as PartialEq and +PartialOrd). In particular, the Debug implementation for BStr +shows its bytes as a normal string. For invalid UTF-8, hex escape +sequences are used.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+println!("{:?}", b"foo\xFFbar".as_bstr());
+

fn as_bstr_mut(&mut self) -> &mut BStr

Return this byte slice as a &mut BStr.

+

Use &mut BStr is useful because of its fmt::Debug representation +and various other trait implementations (such as PartialEq and +PartialOrd). In particular, the Debug implementation for BStr +shows its bytes as a normal string. For invalid UTF-8, hex escape +sequences are used.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut bytes = *b"foo\xFFbar";
+println!("{:?}", &mut bytes.as_bstr_mut());
+

fn from_os_str(os_str: &OsStr) -> Option<&[u8]>

Create an immutable byte string from an OS string slice.

+

When the underlying bytes of OS strings are accessible, then this +always succeeds and is zero cost. Otherwise, this returns None if the +given OS string is not valid UTF-8. (For example, when the underlying +bytes are inaccessible on Windows, file paths are allowed to be a +sequence of arbitrary 16-bit integers. Not all such sequences can be +transcoded to valid UTF-8.)

+
Examples
+

Basic usage:

+ +
use std::ffi::OsStr;
+
+use bstr::{B, ByteSlice};
+
+let os_str = OsStr::new("foo");
+let bs = <[u8]>::from_os_str(os_str).expect("should be valid UTF-8");
+assert_eq!(bs, B("foo"));
+

fn from_path(path: &Path) -> Option<&[u8]>

Create an immutable byte string from a file path.

+

When the underlying bytes of paths are accessible, then this always +succeeds and is zero cost. Otherwise, this returns None if the given +path is not valid UTF-8. (For example, when the underlying bytes are +inaccessible on Windows, file paths are allowed to be a sequence of +arbitrary 16-bit integers. Not all such sequences can be transcoded to +valid UTF-8.)

+
Examples
+

Basic usage:

+ +
use std::path::Path;
+
+use bstr::{B, ByteSlice};
+
+let path = Path::new("foo");
+let bs = <[u8]>::from_path(path).expect("should be valid UTF-8");
+assert_eq!(bs, B("foo"));
+

fn to_str(&self) -> Result<&str, Utf8Error>

Safely convert this byte string into a &str if it’s valid UTF-8.

+

If this byte string is not valid UTF-8, then an error is returned. The +error returned indicates the first invalid byte found and the length +of the error.

+

In cases where a lossy conversion to &str is acceptable, then use one +of the to_str_lossy or +to_str_lossy_into +methods.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice, ByteVec};
+
+let s = B("☃βツ").to_str()?;
+assert_eq!("☃βツ", s);
+
+let mut bstring = <Vec<u8>>::from("☃βツ");
+bstring.push(b'\xFF');
+let err = bstring.to_str().unwrap_err();
+assert_eq!(8, err.valid_up_to());
+

unsafe fn to_str_unchecked(&self) -> &str

Unsafely convert this byte string into a &str, without checking for +valid UTF-8.

+
Safety
+

Callers must ensure that this byte string is valid UTF-8 before +calling this method. Converting a byte string into a &str that is +not valid UTF-8 is considered undefined behavior.

+

This routine is useful in performance sensitive contexts where the +UTF-8 validity of the byte string is already known and it is +undesirable to pay the cost of an additional UTF-8 validation check +that to_str performs.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+// SAFETY: This is safe because string literals are guaranteed to be
+// valid UTF-8 by the Rust compiler.
+let s = unsafe { B("☃βツ").to_str_unchecked() };
+assert_eq!("☃βツ", s);
+

fn to_str_lossy(&self) -> Cow<'_, str>

Convert this byte string to a valid UTF-8 string by replacing invalid +UTF-8 bytes with the Unicode replacement codepoint (U+FFFD).

+

If the byte string is already valid UTF-8, then no copying or +allocation is performed and a borrrowed string slice is returned. If +the byte string is not valid UTF-8, then an owned string buffer is +returned with invalid bytes replaced by the replacement codepoint.

+

This method uses the “substitution of maximal subparts” (Unicode +Standard, Chapter 3, Section 9) strategy for inserting the replacement +codepoint. Specifically, a replacement codepoint is inserted whenever a +byte is found that cannot possibly lead to a valid code unit sequence. +If there were previous bytes that represented a prefix of a well-formed +code unit sequence, then all of those bytes are substituted with a +single replacement codepoint. The “substitution of maximal subparts” +strategy is the same strategy used by +W3C’s Encoding standard. +For a more precise description of the maximal subpart strategy, see +the Unicode Standard, Chapter 3, Section 9. See also +Public Review Issue #121.

+

N.B. Rust’s standard library also appears to use the same strategy, +but it does not appear to be an API guarantee.

+
Examples
+

Basic usage:

+ +
use std::borrow::Cow;
+
+use bstr::ByteSlice;
+
+let mut bstring = <Vec<u8>>::from("☃βツ");
+assert_eq!(Cow::Borrowed("☃βツ"), bstring.to_str_lossy());
+
+// Add a byte that makes the sequence invalid.
+bstring.push(b'\xFF');
+assert_eq!(Cow::Borrowed("☃βツ\u{FFFD}"), bstring.to_str_lossy());
+

This demonstrates the “maximal subpart” substitution logic.

+ +
use bstr::{B, ByteSlice};
+
+// \x61 is the ASCII codepoint for 'a'.
+// \xF1\x80\x80 is a valid 3-byte code unit prefix.
+// \xE1\x80 is a valid 2-byte code unit prefix.
+// \xC2 is a valid 1-byte code unit prefix.
+// \x62 is the ASCII codepoint for 'b'.
+//
+// In sum, each of the prefixes is replaced by a single replacement
+// codepoint since none of the prefixes are properly completed. This
+// is in contrast to other strategies that might insert a replacement
+// codepoint for every single byte.
+let bs = B(b"\x61\xF1\x80\x80\xE1\x80\xC2\x62");
+assert_eq!("a\u{FFFD}\u{FFFD}\u{FFFD}b", bs.to_str_lossy());
+

fn to_str_lossy_into(&self, dest: &mut String)

Copy the contents of this byte string into the given owned string +buffer, while replacing invalid UTF-8 code unit sequences with the +Unicode replacement codepoint (U+FFFD).

+

This method uses the same “substitution of maximal subparts” strategy +for inserting the replacement codepoint as the +to_str_lossy method.

+

This routine is useful for amortizing allocation. However, unlike +to_str_lossy, this routine will always copy the contents of this +byte string into the destination buffer, even if this byte string is +valid UTF-8.

+
Examples
+

Basic usage:

+ +
use std::borrow::Cow;
+
+use bstr::ByteSlice;
+
+let mut bstring = <Vec<u8>>::from("☃βツ");
+// Add a byte that makes the sequence invalid.
+bstring.push(b'\xFF');
+
+let mut dest = String::new();
+bstring.to_str_lossy_into(&mut dest);
+assert_eq!("☃βツ\u{FFFD}", dest);
+

fn to_os_str(&self) -> Result<&OsStr, Utf8Error>

Create an OS string slice from this byte string.

+

When OS strings can be constructed from arbitrary byte sequences, this +always succeeds and is zero cost. Otherwise, this returns a UTF-8 +decoding error if this byte string is not valid UTF-8. (For example, +assuming the representation of OsStr is opaque on Windows, file paths +are allowed to be a sequence of arbitrary 16-bit integers. There is +no obvious mapping from an arbitrary sequence of 8-bit integers to an +arbitrary sequence of 16-bit integers. If the representation of OsStr +is even opened up, then this will convert any sequence of bytes to an +OsStr without cost.)

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let os_str = b"foo".to_os_str().expect("should be valid UTF-8");
+assert_eq!(os_str, "foo");
+

fn to_os_str_lossy(&self) -> Cow<'_, OsStr>

Lossily create an OS string slice from this byte string.

+

When OS strings can be constructed from arbitrary byte sequences, this +is zero cost and always returns a slice. Otherwise, this will perform a +UTF-8 check and lossily convert this byte string into valid UTF-8 using +the Unicode replacement codepoint.

+

Note that this can prevent the correct roundtripping of file paths when +the representation of OsStr is opaque.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let os_str = b"foo\xFFbar".to_os_str_lossy();
+assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar");
+

fn to_path(&self) -> Result<&Path, Utf8Error>

Create a path slice from this byte string.

+

When paths can be constructed from arbitrary byte sequences, this +always succeeds and is zero cost. Otherwise, this returns a UTF-8 +decoding error if this byte string is not valid UTF-8. (For example, +assuming the representation of Path is opaque on Windows, file paths +are allowed to be a sequence of arbitrary 16-bit integers. There is +no obvious mapping from an arbitrary sequence of 8-bit integers to an +arbitrary sequence of 16-bit integers. If the representation of Path +is even opened up, then this will convert any sequence of bytes to an +Path without cost.)

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let path = b"foo".to_path().expect("should be valid UTF-8");
+assert_eq!(path.as_os_str(), "foo");
+

fn to_path_lossy(&self) -> Cow<'_, Path>

Lossily create a path slice from this byte string.

+

When paths can be constructed from arbitrary byte sequences, this is +zero cost and always returns a slice. Otherwise, this will perform a +UTF-8 check and lossily convert this byte string into valid UTF-8 using +the Unicode replacement codepoint.

+

Note that this can prevent the correct roundtripping of file paths when +the representation of Path is opaque.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"foo\xFFbar";
+let path = bs.to_path_lossy();
+assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar");
+

fn repeatn(&self, n: usize) -> Vec<u8>

Create a new byte string by repeating this byte string n times.

+
Panics
+

This function panics if the capacity of the new byte string would +overflow.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(b"foo".repeatn(4), B("foofoofoofoo"));
+assert_eq!(b"foo".repeatn(0), B(""));
+

fn contains_str<B>(&self, needle: B) -> boolwhere + B: AsRef<[u8]>,

Returns true if and only if this byte string contains the given needle.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert!(b"foo bar".contains_str("foo"));
+assert!(b"foo bar".contains_str("bar"));
+assert!(!b"foo".contains_str("foobar"));
+

fn starts_with_str<B>(&self, prefix: B) -> boolwhere + B: AsRef<[u8]>,

Returns true if and only if this byte string has the given prefix.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert!(b"foo bar".starts_with_str("foo"));
+assert!(!b"foo bar".starts_with_str("bar"));
+assert!(!b"foo".starts_with_str("foobar"));
+

fn ends_with_str<B>(&self, suffix: B) -> boolwhere + B: AsRef<[u8]>,

Returns true if and only if this byte string has the given suffix.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert!(b"foo bar".ends_with_str("bar"));
+assert!(!b"foo bar".ends_with_str("foo"));
+assert!(!b"bar".ends_with_str("foobar"));
+

fn find<B>(&self, needle: B) -> Option<usize>where + B: AsRef<[u8]>,

Returns the index of the first occurrence of the given needle.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

Note that if you’re are searching for the same needle in many +different small haystacks, it may be faster to initialize a +Finder once, and reuse it for each search.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar baz";
+assert_eq!(Some(0), s.find("foo"));
+assert_eq!(Some(4), s.find("bar"));
+assert_eq!(None, s.find("quux"));
+

fn rfind<B>(&self, needle: B) -> Option<usize>where + B: AsRef<[u8]>,

Returns the index of the last occurrence of the given needle.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

Note that if you’re are searching for the same needle in many +different small haystacks, it may be faster to initialize a +FinderReverse once, and reuse it for +each search.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar baz";
+assert_eq!(Some(0), s.rfind("foo"));
+assert_eq!(Some(4), s.rfind("bar"));
+assert_eq!(Some(8), s.rfind("ba"));
+assert_eq!(None, s.rfind("quux"));
+

fn find_iter<B, 'h, 'n>(&'h self, needle: &'n B) -> Find<'h, 'n>where + B: AsRef<[u8]> + ?Sized,

Returns an iterator of the non-overlapping occurrences of the given +needle. The iterator yields byte offset positions indicating the start +of each match.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar foo foo quux foo";
+let matches: Vec<usize> = s.find_iter("foo").collect();
+assert_eq!(matches, vec![0, 8, 12, 21]);
+

An empty string matches at every position, including the position +immediately following the last byte:

+ +
use bstr::ByteSlice;
+
+let matches: Vec<usize> = b"foo".find_iter("").collect();
+assert_eq!(matches, vec![0, 1, 2, 3]);
+
+let matches: Vec<usize> = b"".find_iter("").collect();
+assert_eq!(matches, vec![0]);
+

fn rfind_iter<B, 'h, 'n>(&'h self, needle: &'n B) -> FindReverse<'h, 'n>where + B: AsRef<[u8]> + ?Sized,

Returns an iterator of the non-overlapping occurrences of the given +needle in reverse. The iterator yields byte offset positions indicating +the start of each match.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the needle and the haystack. That is, this runs +in O(needle.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foo bar foo foo quux foo";
+let matches: Vec<usize> = s.rfind_iter("foo").collect();
+assert_eq!(matches, vec![21, 12, 8, 0]);
+

An empty string matches at every position, including the position +immediately following the last byte:

+ +
use bstr::ByteSlice;
+
+let matches: Vec<usize> = b"foo".rfind_iter("").collect();
+assert_eq!(matches, vec![3, 2, 1, 0]);
+
+let matches: Vec<usize> = b"".rfind_iter("").collect();
+assert_eq!(matches, vec![0]);
+

fn find_byte(&self, byte: u8) -> Option<usize>

Returns the index of the first occurrence of the given byte. If the +byte does not occur in this byte string, then None is returned.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(Some(10), b"foo bar baz".find_byte(b'z'));
+assert_eq!(None, b"foo bar baz".find_byte(b'y'));
+

fn rfind_byte(&self, byte: u8) -> Option<usize>

Returns the index of the last occurrence of the given byte. If the +byte does not occur in this byte string, then None is returned.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(Some(10), b"foo bar baz".rfind_byte(b'z'));
+assert_eq!(None, b"foo bar baz".rfind_byte(b'y'));
+

fn find_char(&self, ch: char) -> Option<usize>

Returns the index of the first occurrence of the given codepoint. +If the codepoint does not occur in this byte string, then None is +returned.

+

Note that if one searches for the replacement codepoint, \u{FFFD}, +then only explicit occurrences of that encoding will be found. Invalid +UTF-8 sequences will not be matched.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(Some(10), b"foo bar baz".find_char('z'));
+assert_eq!(Some(4), B("αβγγδ").find_char('γ'));
+assert_eq!(None, b"foo bar baz".find_char('y'));
+

fn rfind_char(&self, ch: char) -> Option<usize>

Returns the index of the last occurrence of the given codepoint. +If the codepoint does not occur in this byte string, then None is +returned.

+

Note that if one searches for the replacement codepoint, \u{FFFD}, +then only explicit occurrences of that encoding will be found. Invalid +UTF-8 sequences will not be matched.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(Some(10), b"foo bar baz".rfind_char('z'));
+assert_eq!(Some(6), B("αβγγδ").rfind_char('γ'));
+assert_eq!(None, b"foo bar baz".rfind_char('y'));
+

fn find_byteset<B>(&self, byteset: B) -> Option<usize>where + B: AsRef<[u8]>,

Returns the index of the first occurrence of any of the bytes in the +provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and +duplicate bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz".find_byteset(b"zr"), Some(6));
+assert_eq!(b"foo baz bar".find_byteset(b"bzr"), Some(4));
+assert_eq!(None, b"foo baz bar".find_byteset(b"\t\n"));
+// The empty byteset never matches.
+assert_eq!(None, b"abc".find_byteset(b""));
+assert_eq!(None, b"".find_byteset(b""));
+

fn find_not_byteset<B>(&self, byteset: B) -> Option<usize>where + B: AsRef<[u8]>,

Returns the index of the first occurrence of a byte that is not a +member of the provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and +duplicate bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz".find_not_byteset(b"fo "), Some(4));
+assert_eq!(b"\t\tbaz bar".find_not_byteset(b" \t\r\n"), Some(2));
+assert_eq!(b"foo\nbaz\tbar".find_not_byteset(b"\t\n"), Some(0));
+// The negation of the empty byteset matches everything.
+assert_eq!(Some(0), b"abc".find_not_byteset(b""));
+// But an empty string never contains anything.
+assert_eq!(None, b"".find_not_byteset(b""));
+

fn rfind_byteset<B>(&self, byteset: B) -> Option<usize>where + B: AsRef<[u8]>,

Returns the index of the last occurrence of any of the bytes in the +provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and duplicate +bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz".rfind_byteset(b"agb"), Some(9));
+assert_eq!(b"foo baz bar".rfind_byteset(b"rabz "), Some(10));
+assert_eq!(b"foo baz bar".rfind_byteset(b"\n123"), None);
+

fn rfind_not_byteset<B>(&self, byteset: B) -> Option<usize>where + B: AsRef<[u8]>,

Returns the index of the last occurrence of a byte that is not a member +of the provided set.

+

The byteset may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8], but +note that passing a &str which contains multibyte characters may not +behave as you expect: each byte in the &str is treated as an +individual member of the byte set.

+

Note that order is irrelevant for the byteset parameter, and +duplicate bytes present in its body are ignored.

+
Complexity
+

This routine is guaranteed to have worst case linear time complexity +with respect to both the set of bytes and the haystack. That is, this +runs in O(byteset.len() + haystack.len()) time.

+

This routine is also guaranteed to have worst case constant space +complexity.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(b"foo bar baz,\t".rfind_not_byteset(b",\t"), Some(10));
+assert_eq!(b"foo baz bar".rfind_not_byteset(b"rabz "), Some(2));
+assert_eq!(None, b"foo baz bar".rfind_not_byteset(b"barfoz "));
+

fn fields(&self) -> Fields<'_>

Returns an iterator over the fields in a byte string, separated +by contiguous whitespace (according to the Unicode property +White_Space).

+
Example
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("  foo\tbar\t\u{2003}\nquux   \n");
+let fields: Vec<&[u8]> = s.fields().collect();
+assert_eq!(fields, vec![B("foo"), B("bar"), B("quux")]);
+

A byte string consisting of just whitespace yields no elements:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(0, B("  \n\t\u{2003}\n  \t").fields().count());
+

fn fields_with<F>(&self, f: F) -> FieldsWith<'_, F>where + F: FnMut(char) -> bool,

Returns an iterator over the fields in a byte string, separated by +contiguous codepoints satisfying the given predicate.

+

If this byte string is not valid UTF-8, then the given closure will +be called with a Unicode replacement codepoint when invalid UTF-8 +bytes are seen.

+
Example
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo999999bar1quux123456";
+let fields: Vec<&[u8]> = s.fields_with(|c| c.is_numeric()).collect();
+assert_eq!(fields, vec![B("foo"), B("bar"), B("quux")]);
+

A byte string consisting of all codepoints satisfying the predicate +yields no elements:

+ +
use bstr::ByteSlice;
+
+assert_eq!(0, b"1911354563".fields_with(|c| c.is_numeric()).count());
+

fn split_str<B, 'h, 's>(&'h self, splitter: &'s B) -> Split<'h, 's>where + B: AsRef<[u8]> + ?Sized,

Returns an iterator over substrings of this byte string, separated +by the given byte string. Each element yielded is guaranteed not to +include the splitter substring.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"Mary had a little lamb".split_str(" ").collect();
+assert_eq!(x, vec![
+    B("Mary"), B("had"), B("a"), B("little"), B("lamb"),
+]);
+
+let x: Vec<&[u8]> = b"".split_str("X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<&[u8]> = b"lionXXtigerXleopard".split_str("X").collect();
+assert_eq!(x, vec![B("lion"), B(""), B("tiger"), B("leopard")]);
+
+let x: Vec<&[u8]> = b"lion::tiger::leopard".split_str("::").collect();
+assert_eq!(x, vec![B("lion"), B("tiger"), B("leopard")]);
+

If a string contains multiple contiguous separators, you will end up +with empty strings yielded by the iterator:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"||||a||b|c".split_str("|").collect();
+assert_eq!(x, vec![
+    B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
+]);
+
+let x: Vec<&[u8]> = b"(///)".split_str("/").collect();
+assert_eq!(x, vec![B("("), B(""), B(""), B(")")]);
+

Separators at the start or end of a string are neighbored by empty +strings.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"010".split_str("0").collect();
+assert_eq!(x, vec![B(""), B("1"), B("")]);
+

When the empty string is used as a separator, it splits every byte +in the byte string, along with the beginning and end of the byte +string.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"rust".split_str("").collect();
+assert_eq!(x, vec![
+    B(""), B("r"), B("u"), B("s"), B("t"), B(""),
+]);
+
+// Splitting by an empty string is not UTF-8 aware. Elements yielded
+// may not be valid UTF-8!
+let x: Vec<&[u8]> = B("☃").split_str("").collect();
+assert_eq!(x, vec![
+    B(""), B(b"\xE2"), B(b"\x98"), B(b"\x83"), B(""),
+]);
+

Contiguous separators, especially whitespace, can lead to possibly +surprising behavior. For example, this code is correct:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"    a  b c".split_str(" ").collect();
+assert_eq!(x, vec![
+    B(""), B(""), B(""), B(""), B("a"), B(""), B("b"), B("c"),
+]);
+

It does not give you ["a", "b", "c"]. For that behavior, use +fields instead.

+

fn rsplit_str<B, 'h, 's>(&'h self, splitter: &'s B) -> SplitReverse<'h, 's>where + B: AsRef<[u8]> + ?Sized,

Returns an iterator over substrings of this byte string, separated by +the given byte string, in reverse. Each element yielded is guaranteed +not to include the splitter substring.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> =
+    b"Mary had a little lamb".rsplit_str(" ").collect();
+assert_eq!(x, vec![
+    B("lamb"), B("little"), B("a"), B("had"), B("Mary"),
+]);
+
+let x: Vec<&[u8]> = b"".rsplit_str("X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<&[u8]> = b"lionXXtigerXleopard".rsplit_str("X").collect();
+assert_eq!(x, vec![B("leopard"), B("tiger"), B(""), B("lion")]);
+
+let x: Vec<&[u8]> = b"lion::tiger::leopard".rsplit_str("::").collect();
+assert_eq!(x, vec![B("leopard"), B("tiger"), B("lion")]);
+

If a string contains multiple contiguous separators, you will end up +with empty strings yielded by the iterator:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"||||a||b|c".rsplit_str("|").collect();
+assert_eq!(x, vec![
+    B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
+]);
+
+let x: Vec<&[u8]> = b"(///)".rsplit_str("/").collect();
+assert_eq!(x, vec![B(")"), B(""), B(""), B("(")]);
+

Separators at the start or end of a string are neighbored by empty +strings.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"010".rsplit_str("0").collect();
+assert_eq!(x, vec![B(""), B("1"), B("")]);
+

When the empty string is used as a separator, it splits every byte +in the byte string, along with the beginning and end of the byte +string.

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"rust".rsplit_str("").collect();
+assert_eq!(x, vec![
+    B(""), B("t"), B("s"), B("u"), B("r"), B(""),
+]);
+
+// Splitting by an empty string is not UTF-8 aware. Elements yielded
+// may not be valid UTF-8!
+let x: Vec<&[u8]> = B("☃").rsplit_str("").collect();
+assert_eq!(x, vec![B(""), B(b"\x83"), B(b"\x98"), B(b"\xE2"), B("")]);
+

Contiguous separators, especially whitespace, can lead to possibly +surprising behavior. For example, this code is correct:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<&[u8]> = b"    a  b c".rsplit_str(" ").collect();
+assert_eq!(x, vec![
+    B("c"), B("b"), B(""), B("a"), B(""), B(""), B(""), B(""),
+]);
+

It does not give you ["a", "b", "c"].

+

fn split_once_str<B, 'a>(&'a self, splitter: &B) -> Option<(&'a [u8], &'a [u8])>where + B: AsRef<[u8]> + ?Sized,

Split this byte string at the first occurrence of splitter.

+

If the splitter is found in the byte string, returns a tuple +containing the parts of the string before and after the first occurrence +of splitter respectively. Otherwise, if there are no occurrences of +splitter in the byte string, returns None.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

If you need to split on the last instance of a delimiter instead, see +the ByteSlice::rsplit_once_str method .

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(
+    B("foo,bar").split_once_str(","),
+    Some((B("foo"), B("bar"))),
+);
+assert_eq!(
+    B("foo,bar,baz").split_once_str(","),
+    Some((B("foo"), B("bar,baz"))),
+);
+assert_eq!(B("foo").split_once_str(","), None);
+assert_eq!(B("foo,").split_once_str(b","), Some((B("foo"), B(""))));
+assert_eq!(B(",foo").split_once_str(b","), Some((B(""), B("foo"))));
+

fn rsplit_once_str<B, 'a>( + &'a self, + splitter: &B +) -> Option<(&'a [u8], &'a [u8])>where + B: AsRef<[u8]> + ?Sized,

Split this byte string at the last occurrence of splitter.

+

If the splitter is found in the byte string, returns a tuple +containing the parts of the string before and after the last occurrence +of splitter, respectively. Otherwise, if there are no occurrences of +splitter in the byte string, returns None.

+

The splitter may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+

If you need to split on the first instance of a delimiter instead, see +the ByteSlice::split_once_str method.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert_eq!(
+    B("foo,bar").rsplit_once_str(","),
+    Some((B("foo"), B("bar"))),
+);
+assert_eq!(
+    B("foo,bar,baz").rsplit_once_str(","),
+    Some((B("foo,bar"), B("baz"))),
+);
+assert_eq!(B("foo").rsplit_once_str(","), None);
+assert_eq!(B("foo,").rsplit_once_str(b","), Some((B("foo"), B(""))));
+assert_eq!(B(",foo").rsplit_once_str(b","), Some((B(""), B("foo"))));
+

fn splitn_str<B, 'h, 's>( + &'h self, + limit: usize, + splitter: &'s B +) -> SplitN<'h, 's>where + B: AsRef<[u8]> + ?Sized,

Returns an iterator of at most limit substrings of this byte string, +separated by the given byte string. If limit substrings are yielded, +then the last substring will contain the remainder of this byte string.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<_> = b"Mary had a little lamb".splitn_str(3, " ").collect();
+assert_eq!(x, vec![B("Mary"), B("had"), B("a little lamb")]);
+
+let x: Vec<_> = b"".splitn_str(3, "X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<_> = b"lionXXtigerXleopard".splitn_str(3, "X").collect();
+assert_eq!(x, vec![B("lion"), B(""), B("tigerXleopard")]);
+
+let x: Vec<_> = b"lion::tiger::leopard".splitn_str(2, "::").collect();
+assert_eq!(x, vec![B("lion"), B("tiger::leopard")]);
+
+let x: Vec<_> = b"abcXdef".splitn_str(1, "X").collect();
+assert_eq!(x, vec![B("abcXdef")]);
+
+let x: Vec<_> = b"abcdef".splitn_str(2, "X").collect();
+assert_eq!(x, vec![B("abcdef")]);
+
+let x: Vec<_> = b"abcXdef".splitn_str(0, "X").collect();
+assert!(x.is_empty());
+

fn rsplitn_str<B, 'h, 's>( + &'h self, + limit: usize, + splitter: &'s B +) -> SplitNReverse<'h, 's>where + B: AsRef<[u8]> + ?Sized,

Returns an iterator of at most limit substrings of this byte string, +separated by the given byte string, in reverse. If limit substrings +are yielded, then the last substring will contain the remainder of this +byte string.

+

The needle may be any type that can be cheaply converted into a +&[u8]. This includes, but is not limited to, &str and &[u8].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let x: Vec<_> =
+    b"Mary had a little lamb".rsplitn_str(3, " ").collect();
+assert_eq!(x, vec![B("lamb"), B("little"), B("Mary had a")]);
+
+let x: Vec<_> = b"".rsplitn_str(3, "X").collect();
+assert_eq!(x, vec![b""]);
+
+let x: Vec<_> = b"lionXXtigerXleopard".rsplitn_str(3, "X").collect();
+assert_eq!(x, vec![B("leopard"), B("tiger"), B("lionX")]);
+
+let x: Vec<_> = b"lion::tiger::leopard".rsplitn_str(2, "::").collect();
+assert_eq!(x, vec![B("leopard"), B("lion::tiger")]);
+
+let x: Vec<_> = b"abcXdef".rsplitn_str(1, "X").collect();
+assert_eq!(x, vec![B("abcXdef")]);
+
+let x: Vec<_> = b"abcdef".rsplitn_str(2, "X").collect();
+assert_eq!(x, vec![B("abcdef")]);
+
+let x: Vec<_> = b"abcXdef".rsplitn_str(0, "X").collect();
+assert!(x.is_empty());
+

fn replace<N, R>(&self, needle: N, replacement: R) -> Vec<u8> where + N: AsRef<[u8]>, + R: AsRef<[u8]>,

Replace all matches of the given needle with the given replacement, and +the result as a new Vec<u8>.

+

This routine is useful as a convenience. If you need to reuse an +allocation, use replace_into instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"this is old".replace("old", "new");
+assert_eq!(s, "this is new".as_bytes());
+

When the pattern doesn’t match:

+ +
use bstr::ByteSlice;
+
+let s = b"this is old".replace("nada nada", "limonada");
+assert_eq!(s, "this is old".as_bytes());
+

When the needle is an empty string:

+ +
use bstr::ByteSlice;
+
+let s = b"foo".replace("", "Z");
+assert_eq!(s, "ZfZoZoZ".as_bytes());
+

fn replacen<N, R>(&self, needle: N, replacement: R, limit: usize) -> Vec<u8> where + N: AsRef<[u8]>, + R: AsRef<[u8]>,

Replace up to limit matches of the given needle with the given +replacement, and the result as a new Vec<u8>.

+

This routine is useful as a convenience. If you need to reuse an +allocation, use replacen_into instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foofoo".replacen("o", "z", 2);
+assert_eq!(s, "fzzfoo".as_bytes());
+

When the pattern doesn’t match:

+ +
use bstr::ByteSlice;
+
+let s = b"foofoo".replacen("a", "z", 2);
+assert_eq!(s, "foofoo".as_bytes());
+

When the needle is an empty string:

+ +
use bstr::ByteSlice;
+
+let s = b"foo".replacen("", "Z", 2);
+assert_eq!(s, "ZfZoo".as_bytes());
+

fn replace_into<N, R>(&self, needle: N, replacement: R, dest: &mut Vec<u8>)where + N: AsRef<[u8]>, + R: AsRef<[u8]>,

Replace all matches of the given needle with the given replacement, +and write the result into the provided Vec<u8>.

+

This does not clear dest before writing to it.

+

This routine is useful for reusing allocation. For a more convenient +API, use replace instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"this is old";
+
+let mut dest = vec![];
+s.replace_into("old", "new", &mut dest);
+assert_eq!(dest, "this is new".as_bytes());
+

When the pattern doesn’t match:

+ +
use bstr::ByteSlice;
+
+let s = b"this is old";
+
+let mut dest = vec![];
+s.replace_into("nada nada", "limonada", &mut dest);
+assert_eq!(dest, "this is old".as_bytes());
+

When the needle is an empty string:

+ +
use bstr::ByteSlice;
+
+let s = b"foo";
+
+let mut dest = vec![];
+s.replace_into("", "Z", &mut dest);
+assert_eq!(dest, "ZfZoZoZ".as_bytes());
+

fn replacen_into<N, R>( + &self, + needle: N, + replacement: R, + limit: usize, + dest: &mut Vec<u8> +)where + N: AsRef<[u8]>, + R: AsRef<[u8]>,

Replace up to limit matches of the given needle with the given +replacement, and write the result into the provided Vec<u8>.

+

This does not clear dest before writing to it.

+

This routine is useful for reusing allocation. For a more convenient +API, use replacen instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let s = b"foofoo";
+
+let mut dest = vec![];
+s.replacen_into("o", "z", 2, &mut dest);
+assert_eq!(dest, "fzzfoo".as_bytes());
+

When the pattern doesn’t match:

+ +
use bstr::ByteSlice;
+
+let s = b"foofoo";
+
+let mut dest = vec![];
+s.replacen_into("a", "z", 2, &mut dest);
+assert_eq!(dest, "foofoo".as_bytes());
+

When the needle is an empty string:

+ +
use bstr::ByteSlice;
+
+let s = b"foo";
+
+let mut dest = vec![];
+s.replacen_into("", "Z", 2, &mut dest);
+assert_eq!(dest, "ZfZoo".as_bytes());
+

fn bytes(&self) -> Bytes<'_>

Returns an iterator over the bytes in this byte string.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"foobar";
+let bytes: Vec<u8> = bs.bytes().collect();
+assert_eq!(bytes, bs);
+

fn chars(&self) -> Chars<'_>

Returns an iterator over the Unicode scalar values in this byte string. +If invalid UTF-8 is encountered, then the Unicode replacement codepoint +is yielded instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<char> = bs.chars().collect();
+assert_eq!(vec!['☃', '\u{FFFD}', '𝞃', '\u{FFFD}', 'a'], chars);
+

Codepoints can also be iterated over in reverse:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<char> = bs.chars().rev().collect();
+assert_eq!(vec!['a', '\u{FFFD}', '𝞃', '\u{FFFD}', '☃'], chars);
+

fn char_indices(&self) -> CharIndices<'_>

Returns an iterator over the Unicode scalar values in this byte string +along with their starting and ending byte index positions. If invalid +UTF-8 is encountered, then the Unicode replacement codepoint is yielded +instead.

+

Note that this is slightly different from the CharIndices iterator +provided by the standard library. Aside from working on possibly +invalid UTF-8, this iterator provides both the corresponding starting +and ending byte indices of each codepoint yielded. The ending position +is necessary to slice the original byte string when invalid UTF-8 bytes +are converted into a Unicode replacement codepoint, since a single +replacement codepoint can substitute anywhere from 1 to 3 invalid bytes +(inclusive).

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<(usize, usize, char)> = bs.char_indices().collect();
+assert_eq!(chars, vec![
+    (0, 3, '☃'),
+    (3, 4, '\u{FFFD}'),
+    (4, 8, '𝞃'),
+    (8, 10, '\u{FFFD}'),
+    (10, 11, 'a'),
+]);
+

Codepoints can also be iterated over in reverse:

+ +
use bstr::ByteSlice;
+
+let bs = b"\xE2\x98\x83\xFF\xF0\x9D\x9E\x83\xE2\x98\x61";
+let chars: Vec<(usize, usize, char)> = bs
+    .char_indices()
+    .rev()
+    .collect();
+assert_eq!(chars, vec![
+    (10, 11, 'a'),
+    (8, 10, '\u{FFFD}'),
+    (4, 8, '𝞃'),
+    (3, 4, '\u{FFFD}'),
+    (0, 3, '☃'),
+]);
+

fn utf8_chunks(&self) -> Utf8Chunks<'_>

Iterate over chunks of valid UTF-8.

+

The iterator returned yields chunks of valid UTF-8 separated by invalid +UTF-8 bytes, if they exist. Invalid UTF-8 bytes are always 1-3 bytes, +which are determined via the “substitution of maximal subparts” +strategy described in the docs for the +ByteSlice::to_str_lossy +method.

+
Examples
+

This example shows how to gather all valid and invalid chunks from a +byte slice:

+ +
use bstr::{ByteSlice, Utf8Chunk};
+
+let bytes = b"foo\xFD\xFEbar\xFF";
+
+let (mut valid_chunks, mut invalid_chunks) = (vec![], vec![]);
+for chunk in bytes.utf8_chunks() {
+    if !chunk.valid().is_empty() {
+        valid_chunks.push(chunk.valid());
+    }
+    if !chunk.invalid().is_empty() {
+        invalid_chunks.push(chunk.invalid());
+    }
+}
+
+assert_eq!(valid_chunks, vec!["foo", "bar"]);
+assert_eq!(invalid_chunks, vec![b"\xFD", b"\xFE", b"\xFF"]);
+

fn graphemes(&self) -> Graphemes<'_>

Returns an iterator over the grapheme clusters in this byte string. +If invalid UTF-8 is encountered, then the Unicode replacement codepoint +is yielded instead.

+
Examples
+

This example shows how multiple codepoints can combine to form a +single grapheme cluster:

+ +
use bstr::ByteSlice;
+
+let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
+let graphemes: Vec<&str> = bs.graphemes().collect();
+assert_eq!(vec!["à̖", "🇺🇸"], graphemes);
+

This shows that graphemes can be iterated over in reverse:

+ +
use bstr::ByteSlice;
+
+let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
+let graphemes: Vec<&str> = bs.graphemes().rev().collect();
+assert_eq!(vec!["🇺🇸", "à̖"], graphemes);
+

fn grapheme_indices(&self) -> GraphemeIndices<'_>

Returns an iterator over the grapheme clusters in this byte string +along with their starting and ending byte index positions. If invalid +UTF-8 is encountered, then the Unicode replacement codepoint is yielded +instead.

+
Examples
+

This example shows how to get the byte offsets of each individual +grapheme cluster:

+ +
use bstr::ByteSlice;
+
+let bs = "a\u{0300}\u{0316}\u{1F1FA}\u{1F1F8}".as_bytes();
+let graphemes: Vec<(usize, usize, &str)> =
+    bs.grapheme_indices().collect();
+assert_eq!(vec![(0, 5, "à̖"), (5, 13, "🇺🇸")], graphemes);
+

This example shows what happens when invalid UTF-8 is encountered. Note +that the offsets are valid indices into the original string, and do +not necessarily correspond to the length of the &str returned!

+ +
use bstr::{ByteSlice, ByteVec};
+
+let mut bytes = vec![];
+bytes.push_str("a\u{0300}\u{0316}");
+bytes.push(b'\xFF');
+bytes.push_str("\u{1F1FA}\u{1F1F8}");
+
+let graphemes: Vec<(usize, usize, &str)> =
+    bytes.grapheme_indices().collect();
+assert_eq!(
+    graphemes,
+    vec![(0, 5, "à̖"), (5, 6, "\u{FFFD}"), (6, 14, "🇺🇸")]
+);
+

fn words(&self) -> Words<'_>

Returns an iterator over the words in this byte string. If invalid +UTF-8 is encountered, then the Unicode replacement codepoint is yielded +instead.

+

This is similar to +words_with_breaks, +except it only returns elements that contain a “word” character. A word +character is defined by UTS #18 (Annex C) to be the combination of the +Alphabetic and Join_Control properties, along with the +Decimal_Number, Mark and Connector_Punctuation general +categories.

+

Since words are made up of one or more codepoints, this iterator +yields &str elements. When invalid UTF-8 is encountered, replacement +codepoints are substituted.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = br#"The quick ("brown") fox can't jump 32.3 feet, right?"#;
+let words: Vec<&str> = bs.words().collect();
+assert_eq!(words, vec![
+    "The", "quick", "brown", "fox", "can't",
+    "jump", "32.3", "feet", "right",
+]);
+

fn word_indices(&self) -> WordIndices<'_>

Returns an iterator over the words in this byte string along with +their starting and ending byte index positions.

+

This is similar to +words_with_break_indices, +except it only returns elements that contain a “word” character. A word +character is defined by UTS #18 (Annex C) to be the combination of the +Alphabetic and Join_Control properties, along with the +Decimal_Number, Mark and Connector_Punctuation general +categories.

+

Since words are made up of one or more codepoints, this iterator +yields &str elements. When invalid UTF-8 is encountered, replacement +codepoints are substituted.

+
Examples
+

This example shows how to get the byte offsets of each individual +word:

+ +
use bstr::ByteSlice;
+
+let bs = b"can't jump 32.3 feet";
+let words: Vec<(usize, usize, &str)> = bs.word_indices().collect();
+assert_eq!(words, vec![
+    (0, 5, "can't"),
+    (6, 10, "jump"),
+    (11, 15, "32.3"),
+    (16, 20, "feet"),
+]);
+

fn words_with_breaks(&self) -> WordsWithBreaks<'_>

Returns an iterator over the words in this byte string, along with +all breaks between the words. Concatenating all elements yielded by +the iterator results in the original string (modulo Unicode replacement +codepoint substitutions if invalid UTF-8 is encountered).

+

Since words are made up of one or more codepoints, this iterator +yields &str elements. When invalid UTF-8 is encountered, replacement +codepoints are substituted.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = br#"The quick ("brown") fox can't jump 32.3 feet, right?"#;
+let words: Vec<&str> = bs.words_with_breaks().collect();
+assert_eq!(words, vec![
+    "The", " ", "quick", " ", "(", "\"", "brown", "\"", ")",
+    " ", "fox", " ", "can't", " ", "jump", " ", "32.3", " ", "feet",
+    ",", " ", "right", "?",
+]);
+

fn words_with_break_indices(&self) -> WordsWithBreakIndices<'_>

Returns an iterator over the words and their byte offsets in this +byte string, along with all breaks between the words. Concatenating +all elements yielded by the iterator results in the original string +(modulo Unicode replacement codepoint substitutions if invalid UTF-8 is +encountered).

+

Since words are made up of one or more codepoints, this iterator +yields &str elements. When invalid UTF-8 is encountered, replacement +codepoints are substituted.

+
Examples
+

This example shows how to get the byte offsets of each individual +word:

+ +
use bstr::ByteSlice;
+
+let bs = b"can't jump 32.3 feet";
+let words: Vec<(usize, usize, &str)> =
+    bs.words_with_break_indices().collect();
+assert_eq!(words, vec![
+    (0, 5, "can't"),
+    (5, 6, " "),
+    (6, 10, "jump"),
+    (10, 11, " "),
+    (11, 15, "32.3"),
+    (15, 16, " "),
+    (16, 20, "feet"),
+]);
+

fn sentences(&self) -> Sentences<'_>

Returns an iterator over the sentences in this byte string.

+

Typically, a sentence will include its trailing punctuation and +whitespace. Concatenating all elements yielded by the iterator +results in the original string (modulo Unicode replacement codepoint +substitutions if invalid UTF-8 is encountered).

+

Since sentences are made up of one or more codepoints, this iterator +yields &str elements. When invalid UTF-8 is encountered, replacement +codepoints are substituted.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"I want this. Not that. Right now.";
+let sentences: Vec<&str> = bs.sentences().collect();
+assert_eq!(sentences, vec![
+    "I want this. ",
+    "Not that. ",
+    "Right now.",
+]);
+

fn sentence_indices(&self) -> SentenceIndices<'_>

Returns an iterator over the sentences in this byte string along with +their starting and ending byte index positions.

+

Typically, a sentence will include its trailing punctuation and +whitespace. Concatenating all elements yielded by the iterator +results in the original string (modulo Unicode replacement codepoint +substitutions if invalid UTF-8 is encountered).

+

Since sentences are made up of one or more codepoints, this iterator +yields &str elements. When invalid UTF-8 is encountered, replacement +codepoints are substituted.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let bs = b"I want this. Not that. Right now.";
+let sentences: Vec<(usize, usize, &str)> =
+    bs.sentence_indices().collect();
+assert_eq!(sentences, vec![
+    (0, 13, "I want this. "),
+    (13, 23, "Not that. "),
+    (23, 33, "Right now."),
+]);
+

fn lines(&self) -> Lines<'_>

An iterator over all lines in a byte string, without their +terminators.

+

For this iterator, the only line terminators recognized are \r\n and +\n.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"\
+foo
+
+bar\r
+baz
+
+
+quux";
+let lines: Vec<&[u8]> = s.lines().collect();
+assert_eq!(lines, vec![
+    B("foo"), B(""), B("bar"), B("baz"), B(""), B(""), B("quux"),
+]);
+

fn lines_with_terminator(&self) -> LinesWithTerminator<'_>

An iterator over all lines in a byte string, including their +terminators.

+

For this iterator, the only line terminator recognized is \n. (Since +line terminators are included, this also handles \r\n line endings.)

+

Line terminators are only included if they are present in the original +byte string. For example, the last line in a byte string may not end +with a line terminator.

+

Concatenating all elements yielded by this iterator is guaranteed to +yield the original byte string.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"\
+foo
+
+bar\r
+baz
+
+
+quux";
+let lines: Vec<&[u8]> = s.lines_with_terminator().collect();
+assert_eq!(lines, vec![
+    B("foo\n"),
+    B("\n"),
+    B("bar\r\n"),
+    B("baz\n"),
+    B("\n"),
+    B("\n"),
+    B("quux"),
+]);
+

fn trim(&self) -> &[u8]

Return a byte string slice with leading and trailing whitespace +removed.

+

Whitespace is defined according to the terms of the White_Space +Unicode property.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(" foo\tbar\t\u{2003}\n");
+assert_eq!(s.trim(), B("foo\tbar"));
+

fn trim_start(&self) -> &[u8]

Return a byte string slice with leading whitespace removed.

+

Whitespace is defined according to the terms of the White_Space +Unicode property.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(" foo\tbar\t\u{2003}\n");
+assert_eq!(s.trim_start(), B("foo\tbar\t\u{2003}\n"));
+

fn trim_end(&self) -> &[u8]

Return a byte string slice with trailing whitespace removed.

+

Whitespace is defined according to the terms of the White_Space +Unicode property.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(" foo\tbar\t\u{2003}\n");
+assert_eq!(s.trim_end(), B(" foo\tbar"));
+

fn trim_with<F>(&self, trim: F) -> &[u8] where + F: FnMut(char) -> bool,

Return a byte string slice with leading and trailing characters +satisfying the given predicate removed.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo5bar789";
+assert_eq!(s.trim_with(|c| c.is_numeric()), B("foo5bar"));
+

fn trim_start_with<F>(&self, trim: F) -> &[u8] where + F: FnMut(char) -> bool,

Return a byte string slice with leading characters satisfying the given +predicate removed.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo5bar789";
+assert_eq!(s.trim_start_with(|c| c.is_numeric()), B("foo5bar789"));
+

fn trim_end_with<F>(&self, trim: F) -> &[u8] where + F: FnMut(char) -> bool,

Return a byte string slice with trailing characters satisfying the +given predicate removed.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = b"123foo5bar789";
+assert_eq!(s.trim_end_with(|c| c.is_numeric()), B("123foo5bar"));
+

fn to_lowercase(&self) -> Vec<u8>

Returns a new Vec<u8> containing the lowercase equivalent of this +byte string.

+

In this case, lowercase is defined according to the Lowercase Unicode +property.

+

If invalid UTF-8 is seen, or if a character has no lowercase variant, +then it is written to the given buffer unchanged.

+

Note that some characters in this byte string may expand into multiple +characters when changing the case, so the number of bytes written to +the given byte string may not be equivalent to the number of bytes in +this byte string.

+

If you’d like to reuse an allocation for performance reasons, then use +to_lowercase_into instead.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("HELLO Β");
+assert_eq!("hello β".as_bytes(), s.to_lowercase().as_bytes());
+

Scripts without case are not changed:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("农历新年");
+assert_eq!("农历新年".as_bytes(), s.to_lowercase().as_bytes());
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
+assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), s.to_lowercase().as_bytes());
+

fn to_lowercase_into(&self, buf: &mut Vec<u8>)

Writes the lowercase equivalent of this byte string into the given +buffer. The buffer is not cleared before written to.

+

In this case, lowercase is defined according to the Lowercase +Unicode property.

+

If invalid UTF-8 is seen, or if a character has no lowercase variant, +then it is written to the given buffer unchanged.

+

Note that some characters in this byte string may expand into multiple +characters when changing the case, so the number of bytes written to +the given byte string may not be equivalent to the number of bytes in +this byte string.

+

If you don’t need to amortize allocation and instead prefer +convenience, then use to_lowercase instead.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("HELLO Β");
+
+let mut buf = vec![];
+s.to_lowercase_into(&mut buf);
+assert_eq!("hello β".as_bytes(), buf.as_bytes());
+

Scripts without case are not changed:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("农历新年");
+
+let mut buf = vec![];
+s.to_lowercase_into(&mut buf);
+assert_eq!("农历新年".as_bytes(), buf.as_bytes());
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
+
+let mut buf = vec![];
+s.to_lowercase_into(&mut buf);
+assert_eq!(B(b"foo\xFFbar\xE2\x98baz"), buf.as_bytes());
+

fn to_ascii_lowercase(&self) -> Vec<u8>

Returns a new Vec<u8> containing the ASCII lowercase equivalent of +this byte string.

+

In this case, lowercase is only defined in ASCII letters. Namely, the +letters A-Z are converted to a-z. All other bytes remain unchanged. +In particular, the length of the byte string returned is always +equivalent to the length of this byte string.

+

If you’d like to reuse an allocation for performance reasons, then use +make_ascii_lowercase to perform +the conversion in place.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("HELLO Β");
+assert_eq!("hello Β".as_bytes(), s.to_ascii_lowercase().as_bytes());
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(b"FOO\xFFBAR\xE2\x98BAZ");
+assert_eq!(s.to_ascii_lowercase(), B(b"foo\xFFbar\xE2\x98baz"));
+

fn make_ascii_lowercase(&mut self)

Convert this byte string to its lowercase ASCII equivalent in place.

+

In this case, lowercase is only defined in ASCII letters. Namely, the +letters A-Z are converted to a-z. All other bytes remain unchanged.

+

If you don’t need to do the conversion in +place and instead prefer convenience, then use +to_ascii_lowercase instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("HELLO Β");
+s.make_ascii_lowercase();
+assert_eq!(s, "hello Β".as_bytes());
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice, ByteVec};
+
+let mut s = <Vec<u8>>::from_slice(b"FOO\xFFBAR\xE2\x98BAZ");
+s.make_ascii_lowercase();
+assert_eq!(s, B(b"foo\xFFbar\xE2\x98baz"));
+

fn to_uppercase(&self) -> Vec<u8>

Returns a new Vec<u8> containing the uppercase equivalent of this +byte string.

+

In this case, uppercase is defined according to the Uppercase +Unicode property.

+

If invalid UTF-8 is seen, or if a character has no uppercase variant, +then it is written to the given buffer unchanged.

+

Note that some characters in this byte string may expand into multiple +characters when changing the case, so the number of bytes written to +the given byte string may not be equivalent to the number of bytes in +this byte string.

+

If you’d like to reuse an allocation for performance reasons, then use +to_uppercase_into instead.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("hello β");
+assert_eq!(s.to_uppercase(), B("HELLO Β"));
+

Scripts without case are not changed:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("农历新年");
+assert_eq!(s.to_uppercase(), B("农历新年"));
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(b"foo\xFFbar\xE2\x98baz");
+assert_eq!(s.to_uppercase(), B(b"FOO\xFFBAR\xE2\x98BAZ"));
+

fn to_uppercase_into(&self, buf: &mut Vec<u8>)

Writes the uppercase equivalent of this byte string into the given +buffer. The buffer is not cleared before written to.

+

In this case, uppercase is defined according to the Uppercase +Unicode property.

+

If invalid UTF-8 is seen, or if a character has no uppercase variant, +then it is written to the given buffer unchanged.

+

Note that some characters in this byte string may expand into multiple +characters when changing the case, so the number of bytes written to +the given byte string may not be equivalent to the number of bytes in +this byte string.

+

If you don’t need to amortize allocation and instead prefer +convenience, then use to_uppercase instead.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("hello β");
+
+let mut buf = vec![];
+s.to_uppercase_into(&mut buf);
+assert_eq!(buf, B("HELLO Β"));
+

Scripts without case are not changed:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("农历新年");
+
+let mut buf = vec![];
+s.to_uppercase_into(&mut buf);
+assert_eq!(buf, B("农历新年"));
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(b"foo\xFFbar\xE2\x98baz");
+
+let mut buf = vec![];
+s.to_uppercase_into(&mut buf);
+assert_eq!(buf, B(b"FOO\xFFBAR\xE2\x98BAZ"));
+

fn to_ascii_uppercase(&self) -> Vec<u8>

Returns a new Vec<u8> containing the ASCII uppercase equivalent of +this byte string.

+

In this case, uppercase is only defined in ASCII letters. Namely, the +letters a-z are converted to A-Z. All other bytes remain unchanged. +In particular, the length of the byte string returned is always +equivalent to the length of this byte string.

+

If you’d like to reuse an allocation for performance reasons, then use +make_ascii_uppercase to perform +the conversion in place.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let s = B("hello β");
+assert_eq!(s.to_ascii_uppercase(), B("HELLO β"));
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice};
+
+let s = B(b"foo\xFFbar\xE2\x98baz");
+assert_eq!(s.to_ascii_uppercase(), B(b"FOO\xFFBAR\xE2\x98BAZ"));
+

fn make_ascii_uppercase(&mut self)

Convert this byte string to its uppercase ASCII equivalent in place.

+

In this case, uppercase is only defined in ASCII letters. Namely, the +letters a-z are converted to A-Z. All other bytes remain unchanged.

+

If you don’t need to do the conversion in +place and instead prefer convenience, then use +to_ascii_uppercase instead.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+let mut s = <Vec<u8>>::from("hello β");
+s.make_ascii_uppercase();
+assert_eq!(s, B("HELLO β"));
+

Invalid UTF-8 remains as is:

+ +
use bstr::{B, ByteSlice, ByteVec};
+
+let mut s = <Vec<u8>>::from_slice(b"foo\xFFbar\xE2\x98baz");
+s.make_ascii_uppercase();
+assert_eq!(s, B(b"FOO\xFFBAR\xE2\x98BAZ"));
+

fn escape_bytes(&self) -> EscapeBytes<'_>

Escapes this byte string into a sequence of char values.

+

When the sequence of char values is concatenated into a string, the +result is always valid UTF-8. Any unprintable or invalid UTF-8 in this +byte string are escaped using using \xNN notation. Moreover, the +characters \0, \r, \n, \t and \ are escaped as well.

+

This is useful when one wants to get a human readable view of the raw +bytes that is also valid UTF-8.

+

The iterator returned implements the Display trait. So one can do +b"foo\xFFbar".escape_bytes().to_string() to get a String with its +bytes escaped.

+

The dual of this function is ByteVec::unescape_bytes.

+

Note that this is similar to, but not equivalent to the Debug +implementation on BStr and [BString]. The Debug implementations +also use the debug representation for all Unicode codepoints. However, +this escaping routine only escapes individual bytes. All Unicode +codepoints above U+007F are passed through unchanged without any +escaping.

+
Examples
+
use bstr::{B, ByteSlice};
+
+assert_eq!(r"foo\xFFbar", b"foo\xFFbar".escape_bytes().to_string());
+assert_eq!(r"foo\nbar", b"foo\nbar".escape_bytes().to_string());
+assert_eq!(r"foo\tbar", b"foo\tbar".escape_bytes().to_string());
+assert_eq!(r"foo\\bar", b"foo\\bar".escape_bytes().to_string());
+assert_eq!(r"foo☃bar", B("foo☃bar").escape_bytes().to_string());
+

fn reverse_bytes(&mut self)

Reverse the bytes in this string, in place.

+

This is not necessarily a well formed operation! For example, if this +byte string contains valid UTF-8 that isn’t ASCII, then reversing the +string will likely result in invalid UTF-8 and otherwise non-sensical +content.

+

Note that this is equivalent to the generic [u8]::reverse method. +This method is provided to permit callers to explicitly differentiate +between reversing bytes, codepoints and graphemes.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("hello");
+s.reverse_bytes();
+assert_eq!(s, "olleh".as_bytes());
+

fn reverse_chars(&mut self)

Reverse the codepoints in this string, in place.

+

If this byte string is valid UTF-8, then its reversal by codepoint +is also guaranteed to be valid UTF-8.

+

This operation is equivalent to the following, but without allocating:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("foo☃bar");
+
+let mut chars: Vec<char> = s.chars().collect();
+chars.reverse();
+
+let reversed: String = chars.into_iter().collect();
+assert_eq!(reversed, "rab☃oof");
+

Note that this is not necessarily a well formed operation. For example, +if this byte string contains grapheme clusters with more than one +codepoint, then those grapheme clusters will not necessarily be +preserved. If you’d like to preserve grapheme clusters, then use +reverse_graphemes instead.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("foo☃bar");
+s.reverse_chars();
+assert_eq!(s, "rab☃oof".as_bytes());
+

This example shows that not all reversals lead to a well formed string. +For example, in this case, combining marks are used to put accents over +some letters, and those accent marks must appear after the codepoints +they modify.

+ +
use bstr::{B, ByteSlice};
+
+let mut s = <Vec<u8>>::from("résumé");
+s.reverse_chars();
+assert_eq!(s, B(b"\xCC\x81emus\xCC\x81er"));
+

A word of warning: the above example relies on the fact that +résumé is in decomposed normal form, which means there are separate +codepoints for the accents above e. If it is instead in composed +normal form, then the example works:

+ +
use bstr::{B, ByteSlice};
+
+let mut s = <Vec<u8>>::from("résumé");
+s.reverse_chars();
+assert_eq!(s, B("émusér"));
+

The point here is to be cautious and not assume that just because +reverse_chars works in one case, that it therefore works in all +cases.

+

fn reverse_graphemes(&mut self)

Reverse the graphemes in this string, in place.

+

If this byte string is valid UTF-8, then its reversal by grapheme +is also guaranteed to be valid UTF-8.

+

This operation is equivalent to the following, but without allocating:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("foo☃bar");
+
+let mut graphemes: Vec<&str> = s.graphemes().collect();
+graphemes.reverse();
+
+let reversed = graphemes.concat();
+assert_eq!(reversed, "rab☃oof");
+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("foo☃bar");
+s.reverse_graphemes();
+assert_eq!(s, "rab☃oof".as_bytes());
+

This example shows how this correctly handles grapheme clusters, +unlike reverse_chars.

+ +
use bstr::ByteSlice;
+
+let mut s = <Vec<u8>>::from("résumé");
+s.reverse_graphemes();
+assert_eq!(s, "émusér".as_bytes());
+

fn is_ascii(&self) -> bool

Returns true if and only if every byte in this byte string is ASCII.

+

ASCII is an encoding that defines 128 codepoints. A byte corresponds to +an ASCII codepoint if and only if it is in the inclusive range +[0, 127].

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert!(B("abc").is_ascii());
+assert!(!B("☃βツ").is_ascii());
+assert!(!B(b"\xFF").is_ascii());
+

fn is_utf8(&self) -> bool

Returns true if and only if the entire byte string is valid UTF-8.

+

If you need location information about where a byte string’s first +invalid UTF-8 byte is, then use the to_str method.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteSlice};
+
+assert!(B("abc").is_utf8());
+assert!(B("☃βツ").is_utf8());
+// invalid bytes
+assert!(!B(b"abc\xFF").is_utf8());
+// surrogate encoding
+assert!(!B(b"\xED\xA0\x80").is_utf8());
+// incomplete sequence
+assert!(!B(b"\xF0\x9D\x9Ca").is_utf8());
+// overlong sequence
+assert!(!B(b"\xF0\x82\x82\xAC").is_utf8());
+

fn last_byte(&self) -> Option<u8>

Returns the last byte in this byte string, if it’s non-empty. If this +byte string is empty, this returns None.

+

Note that this is like the generic [u8]::last, except this returns +the byte by value instead of a reference to the byte.

+
Examples
+

Basic usage:

+ +
use bstr::ByteSlice;
+
+assert_eq!(Some(b'z'), b"baz".last_byte());
+assert_eq!(None, b"".last_byte());
+

fn find_non_ascii_byte(&self) -> Option<usize>

Returns the index of the first non-ASCII byte in this byte string (if +any such indices exist). Specifically, it returns the index of the +first byte with a value greater than or equal to 0x80.

+
Examples
+

Basic usage:

+ +
use bstr::{ByteSlice, B};
+
+assert_eq!(Some(3), b"abc\xff".find_non_ascii_byte());
+assert_eq!(None, b"abcde".find_non_ascii_byte());
+assert_eq!(Some(0), B("😀").find_non_ascii_byte());
+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

impl ByteSlice for [u8]

§

impl<const N: usize> ByteSlice for [u8; N]

Implementors§

\ No newline at end of file diff --git a/ba2/trait.ByteVec.html b/ba2/trait.ByteVec.html new file mode 100644 index 0000000..64933c0 --- /dev/null +++ b/ba2/trait.ByteVec.html @@ -0,0 +1,501 @@ +ByteVec in ba2 - Rust

Trait ba2::ByteVec

pub trait ByteVec: Sealed {
+
Show 23 methods // Provided methods + fn from_slice<B>(bytes: B) -> Vec<u8> + where B: AsRef<[u8]> { ... } + fn from_os_string(os_str: OsString) -> Result<Vec<u8>, OsString> { ... } + fn from_os_str_lossy<'a>(os_str: &'a OsStr) -> Cow<'a, [u8]> { ... } + fn from_path_buf(path: PathBuf) -> Result<Vec<u8>, PathBuf> { ... } + fn from_path_lossy<'a>(path: &'a Path) -> Cow<'a, [u8]> { ... } + fn unescape_bytes<S>(escaped: S) -> Vec<u8> + where S: AsRef<str> { ... } + fn push_byte(&mut self, byte: u8) { ... } + fn push_char(&mut self, ch: char) { ... } + fn push_str<B>(&mut self, bytes: B) + where B: AsRef<[u8]> { ... } + fn into_string(self) -> Result<String, FromUtf8Error> + where Self: Sized { ... } + fn into_string_lossy(self) -> String + where Self: Sized { ... } + unsafe fn into_string_unchecked(self) -> String + where Self: Sized { ... } + fn into_os_string(self) -> Result<OsString, FromUtf8Error> + where Self: Sized { ... } + fn into_os_string_lossy(self) -> OsString + where Self: Sized { ... } + fn into_path_buf(self) -> Result<PathBuf, FromUtf8Error> + where Self: Sized { ... } + fn into_path_buf_lossy(self) -> PathBuf + where Self: Sized { ... } + fn pop_byte(&mut self) -> Option<u8> { ... } + fn pop_char(&mut self) -> Option<char> { ... } + fn remove_char(&mut self, at: usize) -> char { ... } + fn insert_char(&mut self, at: usize, ch: char) { ... } + fn insert_str<B>(&mut self, at: usize, bytes: B) + where B: AsRef<[u8]> { ... } + fn replace_range<R, B>(&mut self, range: R, replace_with: B) + where R: RangeBounds<usize>, + B: AsRef<[u8]> { ... } + fn drain_bytes<R>(&mut self, range: R) -> DrainBytes<'_> + where R: RangeBounds<usize> { ... } +
}
Expand description

A trait that extends Vec<u8> with string oriented methods.

+

Note that when using the constructor methods, such as +ByteVec::from_slice, one should actually call them using the concrete +type. For example:

+ +
use bstr::{B, ByteVec};
+
+let s = Vec::from_slice(b"abc"); // NOT ByteVec::from_slice("...")
+assert_eq!(s, B("abc"));
+

This trait is sealed and cannot be implemented outside of bstr.

+

Provided Methods§

fn from_slice<B>(bytes: B) -> Vec<u8> where + B: AsRef<[u8]>,

Create a new owned byte string from the given byte slice.

+
Examples
+

Basic usage:

+ +
use bstr::{B, ByteVec};
+
+let s = Vec::from_slice(b"abc");
+assert_eq!(s, B("abc"));
+

fn from_os_string(os_str: OsString) -> Result<Vec<u8>, OsString>

Create a new byte string from an owned OS string.

+

When the underlying bytes of OS strings are accessible, then this +always succeeds and is zero cost. Otherwise, this returns the given +OsString if it is not valid UTF-8.

+
Examples
+

Basic usage:

+ +
use std::ffi::OsString;
+
+use bstr::{B, ByteVec};
+
+let os_str = OsString::from("foo");
+let bs = Vec::from_os_string(os_str).expect("valid UTF-8");
+assert_eq!(bs, B("foo"));
+

fn from_os_str_lossy<'a>(os_str: &'a OsStr) -> Cow<'a, [u8]>

Lossily create a new byte string from an OS string slice.

+

When the underlying bytes of OS strings are accessible, then this is +zero cost and always returns a slice. Otherwise, a UTF-8 check is +performed and if the given OS string is not valid UTF-8, then it is +lossily decoded into valid UTF-8 (with invalid bytes replaced by the +Unicode replacement codepoint).

+
Examples
+

Basic usage:

+ +
use std::ffi::OsStr;
+
+use bstr::{B, ByteVec};
+
+let os_str = OsStr::new("foo");
+let bs = Vec::from_os_str_lossy(os_str);
+assert_eq!(bs, B("foo"));
+

fn from_path_buf(path: PathBuf) -> Result<Vec<u8>, PathBuf>

Create a new byte string from an owned file path.

+

When the underlying bytes of paths are accessible, then this always +succeeds and is zero cost. Otherwise, this returns the given PathBuf +if it is not valid UTF-8.

+
Examples
+

Basic usage:

+ +
use std::path::PathBuf;
+
+use bstr::{B, ByteVec};
+
+let path = PathBuf::from("foo");
+let bs = Vec::from_path_buf(path).expect("must be valid UTF-8");
+assert_eq!(bs, B("foo"));
+

fn from_path_lossy<'a>(path: &'a Path) -> Cow<'a, [u8]>

Lossily create a new byte string from a file path.

+

When the underlying bytes of paths are accessible, then this is +zero cost and always returns a slice. Otherwise, a UTF-8 check is +performed and if the given path is not valid UTF-8, then it is lossily +decoded into valid UTF-8 (with invalid bytes replaced by the Unicode +replacement codepoint).

+
Examples
+

Basic usage:

+ +
use std::path::Path;
+
+use bstr::{B, ByteVec};
+
+let path = Path::new("foo");
+let bs = Vec::from_path_lossy(path);
+assert_eq!(bs, B("foo"));
+

fn unescape_bytes<S>(escaped: S) -> Vec<u8> where + S: AsRef<str>,

Unescapes the given string into its raw bytes.

+

This looks for the escape sequences \xNN, \0, \r, \n, \t +and \ and translates them into their corresponding unescaped form.

+

Incomplete escape sequences or things that look like escape sequences +but are not (for example, \i or \xYZ) are passed through literally.

+

This is the dual of ByteSlice::escape_bytes.

+

Note that the zero or NUL byte may be represented as either \0 or +\x00. Both will be unescaped into the zero byte.

+
Examples
+

This shows basic usage:

+ +
use bstr::{B, BString, ByteVec};
+
+assert_eq!(
+    BString::from(b"foo\xFFbar"),
+    Vec::unescape_bytes(r"foo\xFFbar"),
+);
+assert_eq!(
+    BString::from(b"foo\nbar"),
+    Vec::unescape_bytes(r"foo\nbar"),
+);
+assert_eq!(
+    BString::from(b"foo\tbar"),
+    Vec::unescape_bytes(r"foo\tbar"),
+);
+assert_eq!(
+    BString::from(b"foo\\bar"),
+    Vec::unescape_bytes(r"foo\\bar"),
+);
+assert_eq!(
+    BString::from("foo☃bar"),
+    Vec::unescape_bytes(r"foo☃bar"),
+);
+
+

This shows some examples of how incomplete or “incorrect” escape +sequences get passed through literally.

+ +
use bstr::{B, BString, ByteVec};
+
+// Show some incomplete escape sequences.
+assert_eq!(
+    BString::from(br"\"),
+    Vec::unescape_bytes(r"\"),
+);
+assert_eq!(
+    BString::from(br"\"),
+    Vec::unescape_bytes(r"\\"),
+);
+assert_eq!(
+    BString::from(br"\x"),
+    Vec::unescape_bytes(r"\x"),
+);
+assert_eq!(
+    BString::from(br"\xA"),
+    Vec::unescape_bytes(r"\xA"),
+);
+// And now some that kind of look like escape
+// sequences, but aren't.
+assert_eq!(
+    BString::from(br"\xZ"),
+    Vec::unescape_bytes(r"\xZ"),
+);
+assert_eq!(
+    BString::from(br"\xZZ"),
+    Vec::unescape_bytes(r"\xZZ"),
+);
+assert_eq!(
+    BString::from(br"\i"),
+    Vec::unescape_bytes(r"\i"),
+);
+assert_eq!(
+    BString::from(br"\u"),
+    Vec::unescape_bytes(r"\u"),
+);
+assert_eq!(
+    BString::from(br"\u{2603}"),
+    Vec::unescape_bytes(r"\u{2603}"),
+);
+
+

fn push_byte(&mut self, byte: u8)

Appends the given byte to the end of this byte string.

+

Note that this is equivalent to the generic Vec::push method. This +method is provided to permit callers to explicitly differentiate +between pushing bytes, codepoints and strings.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = <Vec<u8>>::from("abc");
+s.push_byte(b'\xE2');
+s.push_byte(b'\x98');
+s.push_byte(b'\x83');
+assert_eq!(s, "abc☃".as_bytes());
+

fn push_char(&mut self, ch: char)

Appends the given char to the end of this byte string.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = <Vec<u8>>::from("abc");
+s.push_char('1');
+s.push_char('2');
+s.push_char('3');
+assert_eq!(s, "abc123".as_bytes());
+

fn push_str<B>(&mut self, bytes: B)where + B: AsRef<[u8]>,

Appends the given slice to the end of this byte string. This accepts +any type that be converted to a &[u8]. This includes, but is not +limited to, &str, &BStr, and of course, &[u8] itself.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = <Vec<u8>>::from("abc");
+s.push_str(b"123");
+assert_eq!(s, "abc123".as_bytes());
+

fn into_string(self) -> Result<String, FromUtf8Error>where + Self: Sized,

Converts a Vec<u8> into a String if and only if this byte string is +valid UTF-8.

+

If it is not valid UTF-8, then a +FromUtf8Error +is returned. (This error can be used to examine why UTF-8 validation +failed, or to regain the original byte string.)

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let bytes = Vec::from("hello");
+let string = bytes.into_string().unwrap();
+
+assert_eq!("hello", string);
+

If this byte string is not valid UTF-8, then an error will be returned. +That error can then be used to inspect the location at which invalid +UTF-8 was found, or to regain the original byte string:

+ +
use bstr::{B, ByteVec};
+
+let bytes = Vec::from_slice(b"foo\xFFbar");
+let err = bytes.into_string().unwrap_err();
+
+assert_eq!(err.utf8_error().valid_up_to(), 3);
+assert_eq!(err.utf8_error().error_len(), Some(1));
+
+// At no point in this example is an allocation performed.
+let bytes = Vec::from(err.into_vec());
+assert_eq!(bytes, B(b"foo\xFFbar"));
+

fn into_string_lossy(self) -> Stringwhere + Self: Sized,

Lossily converts a Vec<u8> into a String. If this byte string +contains invalid UTF-8, then the invalid bytes are replaced with the +Unicode replacement codepoint.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let bytes = Vec::from_slice(b"foo\xFFbar");
+let string = bytes.into_string_lossy();
+assert_eq!(string, "foo\u{FFFD}bar");
+

unsafe fn into_string_unchecked(self) -> Stringwhere + Self: Sized,

Unsafely convert this byte string into a String, without checking for +valid UTF-8.

+
Safety
+

Callers must ensure that this byte string is valid UTF-8 before +calling this method. Converting a byte string into a String that is +not valid UTF-8 is considered undefined behavior.

+

This routine is useful in performance sensitive contexts where the +UTF-8 validity of the byte string is already known and it is +undesirable to pay the cost of an additional UTF-8 validation check +that into_string performs.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+// SAFETY: This is safe because string literals are guaranteed to be
+// valid UTF-8 by the Rust compiler.
+let s = unsafe { Vec::from("☃βツ").into_string_unchecked() };
+assert_eq!("☃βツ", s);
+

fn into_os_string(self) -> Result<OsString, FromUtf8Error>where + Self: Sized,

Converts this byte string into an OS string, in place.

+

When OS strings can be constructed from arbitrary byte sequences, this +always succeeds and is zero cost. Otherwise, if this byte string is not +valid UTF-8, then an error (with the original byte string) is returned.

+
Examples
+

Basic usage:

+ +
use std::ffi::OsStr;
+
+use bstr::ByteVec;
+
+let bs = Vec::from("foo");
+let os_str = bs.into_os_string().expect("should be valid UTF-8");
+assert_eq!(os_str, OsStr::new("foo"));
+

fn into_os_string_lossy(self) -> OsStringwhere + Self: Sized,

Lossily converts this byte string into an OS string, in place.

+

When OS strings can be constructed from arbitrary byte sequences, this +is zero cost and always returns a slice. Otherwise, this will perform a +UTF-8 check and lossily convert this byte string into valid UTF-8 using +the Unicode replacement codepoint.

+

Note that this can prevent the correct roundtripping of file paths when +the representation of OsString is opaque.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let bs = Vec::from_slice(b"foo\xFFbar");
+let os_str = bs.into_os_string_lossy();
+assert_eq!(os_str.to_string_lossy(), "foo\u{FFFD}bar");
+

fn into_path_buf(self) -> Result<PathBuf, FromUtf8Error>where + Self: Sized,

Converts this byte string into an owned file path, in place.

+

When paths can be constructed from arbitrary byte sequences, this +always succeeds and is zero cost. Otherwise, if this byte string is not +valid UTF-8, then an error (with the original byte string) is returned.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let bs = Vec::from("foo");
+let path = bs.into_path_buf().expect("should be valid UTF-8");
+assert_eq!(path.as_os_str(), "foo");
+

fn into_path_buf_lossy(self) -> PathBufwhere + Self: Sized,

Lossily converts this byte string into an owned file path, in place.

+

When paths can be constructed from arbitrary byte sequences, this is +zero cost and always returns a slice. Otherwise, this will perform a +UTF-8 check and lossily convert this byte string into valid UTF-8 using +the Unicode replacement codepoint.

+

Note that this can prevent the correct roundtripping of file paths when +the representation of PathBuf is opaque.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let bs = Vec::from_slice(b"foo\xFFbar");
+let path = bs.into_path_buf_lossy();
+assert_eq!(path.to_string_lossy(), "foo\u{FFFD}bar");
+

fn pop_byte(&mut self) -> Option<u8>

Removes the last byte from this Vec<u8> and returns it.

+

If this byte string is empty, then None is returned.

+

If the last codepoint in this byte string is not ASCII, then removing +the last byte could make this byte string contain invalid UTF-8.

+

Note that this is equivalent to the generic Vec::pop method. This +method is provided to permit callers to explicitly differentiate +between popping bytes and codepoints.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from("foo");
+assert_eq!(s.pop_byte(), Some(b'o'));
+assert_eq!(s.pop_byte(), Some(b'o'));
+assert_eq!(s.pop_byte(), Some(b'f'));
+assert_eq!(s.pop_byte(), None);
+

fn pop_char(&mut self) -> Option<char>

Removes the last codepoint from this Vec<u8> and returns it.

+

If this byte string is empty, then None is returned. If the last +bytes of this byte string do not correspond to a valid UTF-8 code unit +sequence, then the Unicode replacement codepoint is yielded instead in +accordance with the +replacement codepoint substitution policy.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from("foo");
+assert_eq!(s.pop_char(), Some('o'));
+assert_eq!(s.pop_char(), Some('o'));
+assert_eq!(s.pop_char(), Some('f'));
+assert_eq!(s.pop_char(), None);
+

This shows the replacement codepoint substitution policy. Note that +the first pop yields a replacement codepoint but actually removes two +bytes. This is in contrast with subsequent pops when encountering +\xFF since \xFF is never a valid prefix for any valid UTF-8 +code unit sequence.

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from_slice(b"f\xFF\xFF\xFFoo\xE2\x98");
+assert_eq!(s.pop_char(), Some('\u{FFFD}'));
+assert_eq!(s.pop_char(), Some('o'));
+assert_eq!(s.pop_char(), Some('o'));
+assert_eq!(s.pop_char(), Some('\u{FFFD}'));
+assert_eq!(s.pop_char(), Some('\u{FFFD}'));
+assert_eq!(s.pop_char(), Some('\u{FFFD}'));
+assert_eq!(s.pop_char(), Some('f'));
+assert_eq!(s.pop_char(), None);
+

fn remove_char(&mut self, at: usize) -> char

Removes a char from this Vec<u8> at the given byte position and +returns it.

+

If the bytes at the given position do not lead to a valid UTF-8 code +unit sequence, then a +replacement codepoint is returned instead.

+
Panics
+

Panics if at is larger than or equal to this byte string’s length.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from("foo☃bar");
+assert_eq!(s.remove_char(3), '☃');
+assert_eq!(s, b"foobar");
+

This example shows how the Unicode replacement codepoint policy is +used:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from_slice(b"foo\xFFbar");
+assert_eq!(s.remove_char(3), '\u{FFFD}');
+assert_eq!(s, b"foobar");
+

fn insert_char(&mut self, at: usize, ch: char)

Inserts the given codepoint into this Vec<u8> at a particular byte +position.

+

This is an O(n) operation as it may copy a number of elements in this +byte string proportional to its length.

+
Panics
+

Panics if at is larger than the byte string’s length.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from("foobar");
+s.insert_char(3, '☃');
+assert_eq!(s, "foo☃bar".as_bytes());
+

fn insert_str<B>(&mut self, at: usize, bytes: B)where + B: AsRef<[u8]>,

Inserts the given byte string into this byte string at a particular +byte position.

+

This is an O(n) operation as it may copy a number of elements in this +byte string proportional to its length.

+

The given byte string may be any type that can be cheaply converted +into a &[u8]. This includes, but is not limited to, &str and +&[u8].

+
Panics
+

Panics if at is larger than the byte string’s length.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from("foobar");
+s.insert_str(3, "☃☃☃");
+assert_eq!(s, "foo☃☃☃bar".as_bytes());
+

fn replace_range<R, B>(&mut self, range: R, replace_with: B)where + R: RangeBounds<usize>, + B: AsRef<[u8]>,

Removes the specified range in this byte string and replaces it with +the given bytes. The given bytes do not need to have the same length +as the range provided.

+
Panics
+

Panics if the given range is invalid.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from("foobar");
+s.replace_range(2..4, "xxxxx");
+assert_eq!(s, "foxxxxxar".as_bytes());
+

fn drain_bytes<R>(&mut self, range: R) -> DrainBytes<'_>where + R: RangeBounds<usize>,

Creates a draining iterator that removes the specified range in this +Vec<u8> and yields each of the removed bytes.

+

Note that the elements specified by the given range are removed +regardless of whether the returned iterator is fully exhausted.

+

Also note that is is unspecified how many bytes are removed from the +Vec<u8> if the DrainBytes iterator is leaked.

+
Panics
+

Panics if the given range is not valid.

+
Examples
+

Basic usage:

+ +
use bstr::ByteVec;
+
+let mut s = Vec::from("foobar");
+{
+    let mut drainer = s.drain_bytes(2..4);
+    assert_eq!(drainer.next(), Some(b'o'));
+    assert_eq!(drainer.next(), Some(b'b'));
+    assert_eq!(drainer.next(), None);
+}
+assert_eq!(s, "foar".as_bytes());
+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

impl ByteVec for Vec<u8>

Implementors§

\ No newline at end of file diff --git a/ba2/trait.CompressableFrom.html b/ba2/trait.CompressableFrom.html new file mode 100644 index 0000000..fd50b75 --- /dev/null +++ b/ba2/trait.CompressableFrom.html @@ -0,0 +1,8 @@ +CompressableFrom in ba2 - Rust

Trait ba2::CompressableFrom

source ·
pub trait CompressableFrom<T>: Sealed {
+    // Required methods
+    fn from_compressed(value: T, decompressed_len: usize) -> Self;
+    fn from_decompressed(value: T) -> Self;
+}
Expand description

A trait that creates an optionally compressed container using the given value.

+

Required Methods§

source

fn from_compressed(value: T, decompressed_len: usize) -> Self

Makes a compressed instance of Self using the given data.

+
source

fn from_decompressed(value: T) -> Self

Makes a decompressed instance of Self using the given data.

+

Object Safety§

This trait is not object safe.

Implementors§

source§

impl CompressableFrom<Box<[u8]>> for Chunk<'static>

source§

impl CompressableFrom<Box<[u8]>> for File<'static>

source§

impl<'bytes> CompressableFrom<&'bytes [u8]> for Chunk<'bytes>

source§

impl<'bytes> CompressableFrom<&'bytes [u8]> for File<'bytes>

source§

impl<'bytes, const N: usize> CompressableFrom<&'bytes [u8; N]> for Chunk<'bytes>

source§

impl<'bytes, const N: usize> CompressableFrom<&'bytes [u8; N]> for File<'bytes>

\ No newline at end of file diff --git a/ba2/trait.Reader.html b/ba2/trait.Reader.html new file mode 100644 index 0000000..399372a --- /dev/null +++ b/ba2/trait.Reader.html @@ -0,0 +1,9 @@ +Reader in ba2 - Rust

Trait ba2::Reader

source ·
pub trait Reader<T>: Sealed {
+    type Error;
+    type Item;
+
+    // Required method
+    fn read(source: T) -> Result<Self::Item, Self::Error>;
+}
Expand description

A trait that enables reading from various sources.

+

Required Associated Types§

Required Methods§

source

fn read(source: T) -> Result<Self::Item, Self::Error>

Reads an instance of Self::Item from the given source.

+

Object Safety§

This trait is not object safe.

Implementors§

source§

impl Reader<&File> for ba2::fo4::Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

impl Reader<&File> for ba2::tes3::Archive<'static>

§

type Error = Error

§

type Item = Archive<'static>

source§

impl Reader<&File> for File<'static>

§

type Error = Error

§

type Item = File<'static>

source§

impl Reader<&File> for ba2::tes4::Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

impl Reader<&Path> for ba2::fo4::Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

impl Reader<&Path> for ba2::tes3::Archive<'static>

§

type Error = Error

§

type Item = Archive<'static>

source§

impl Reader<&Path> for File<'static>

§

type Error = Error

§

type Item = File<'static>

source§

impl Reader<&Path> for ba2::tes4::Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

impl<'bytes> Reader<Borrowed<'bytes>> for ba2::fo4::Archive<'bytes>

§

type Error = Error

§

type Item = (Archive<'bytes>, Options)

source§

impl<'bytes> Reader<Borrowed<'bytes>> for ba2::tes3::Archive<'bytes>

§

type Error = Error

§

type Item = Archive<'bytes>

source§

impl<'bytes> Reader<Borrowed<'bytes>> for File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

source§

impl<'bytes> Reader<Borrowed<'bytes>> for ba2::tes4::Archive<'bytes>

§

type Error = Error

§

type Item = (Archive<'bytes>, Options)

source§

impl<'bytes> Reader<Copied<'bytes>> for ba2::fo4::Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

source§

impl<'bytes> Reader<Copied<'bytes>> for ba2::tes3::Archive<'static>

§

type Error = Error

§

type Item = Archive<'static>

source§

impl<'bytes> Reader<Copied<'bytes>> for File<'static>

§

type Error = Error

§

type Item = File<'static>

source§

impl<'bytes> Reader<Copied<'bytes>> for ba2::tes4::Archive<'static>

§

type Error = Error

§

type Item = (Archive<'static>, Options)

\ No newline at end of file diff --git a/ba2/trait.ReaderWithOptions.html b/ba2/trait.ReaderWithOptions.html new file mode 100644 index 0000000..a4ce2c4 --- /dev/null +++ b/ba2/trait.ReaderWithOptions.html @@ -0,0 +1,13 @@ +ReaderWithOptions in ba2 - Rust
pub trait ReaderWithOptions<T>: Sealed {
+    type Error;
+    type Item;
+    type Options;
+
+    // Required method
+    fn read(
+        source: T,
+        options: &Self::Options
+    ) -> Result<Self::Item, Self::Error>;
+}
Expand description

A trait that enables reading from various sources, with configuration options.

+

Required Associated Types§

Required Methods§

source

fn read(source: T, options: &Self::Options) -> Result<Self::Item, Self::Error>

Reads an instance of Self::Item from the given source, using the given options.

+

Object Safety§

This trait is not object safe.

Implementors§

source§

impl ReaderWithOptions<&File> for ba2::fo4::File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

impl ReaderWithOptions<&File> for ba2::tes4::File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

impl ReaderWithOptions<&Path> for ba2::fo4::File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

impl ReaderWithOptions<&Path> for ba2::tes4::File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

impl<'bytes> ReaderWithOptions<Borrowed<'bytes>> for ba2::fo4::File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

§

type Options = ReadOptions

source§

impl<'bytes> ReaderWithOptions<Borrowed<'bytes>> for ba2::tes4::File<'bytes>

§

type Error = Error

§

type Item = File<'bytes>

§

type Options = ReadOptions

source§

impl<'bytes> ReaderWithOptions<Copied<'bytes>> for ba2::fo4::File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

source§

impl<'bytes> ReaderWithOptions<Copied<'bytes>> for ba2::tes4::File<'static>

§

type Error = Error

§

type Item = File<'static>

§

type Options = ReadOptions

\ No newline at end of file diff --git a/crates.js b/crates.js new file mode 100644 index 0000000..054e0ea --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["ba2"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 0000000..47999eb --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Help

Rustdoc help

Back
\ No newline at end of file diff --git a/search-index.js b/search-index.js new file mode 100644 index 0000000..fd13cad --- /dev/null +++ b/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = JSON.parse('{\ +"ba2":{"doc":"Archives come in various flavors, and the specific variant …","t":"DDDIIINEDNQQNEQQQIINNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLALLLLLLLLLLLLLLLKKLLLLLLLLLLLLLLLFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLALLLKKLLLLLLLLLLLLLLLLLLLLLLLLLAALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNDDDDDDDEENNNDNNENNSDDDEDDDDENNNDNNDNNNNNNNNNNNNGNENLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLMMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFFMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLMMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLMLLLMMCCCDDNEDDDNNNNGLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFFMLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNDDDDDDSESNDDDSNESSSSDDDDDDDNNNNNNNSSSNNSSSSGSSSSSSSSESSLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFFFFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNNLLLLLLLLLLLLLLLMM","n":["BStr","BString","Borrowed","ByteSlice","ByteVec","CompressableFrom","Compressed","CompressionResult","Copied","Decompressed","Error","Error","FO4","FileFormat","Item","Item","Options","Reader","ReaderWithOptions","TES3","TES4","as_bstr","as_bstr_mut","as_mut","as_mut","as_mut","as_ref","as_ref","as_ref","as_ref","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","bytes","char_indices","chars","clone","clone","clone","clone_into","clone_into","clone_into","cmp","cmp","contains_str","default","default","default","default","deref","deref","deref_mut","deref_mut","drain_bytes","ends_with_str","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","escape_bytes","fields","fields_with","find","find_byte","find_byteset","find_char","find_iter","find_non_ascii_byte","find_not_byteset","fmt","fmt","fmt","fmt","fmt","fmt","fo4","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_compressed","from_decompressed","from_iter","from_iter","from_iter","from_iter","from_iter","from_iter","from_os_str","from_os_str_lossy","from_os_string","from_path","from_path_buf","from_path_lossy","from_slice","grapheme_indices","graphemes","guess_format","hash","hash","index","index","index","index","index","index","index","index_mut","index_mut","index_mut","index_mut","index_mut","index_mut","index_mut","insert_char","insert_str","into","into","into","into","into","into_os_string","into_os_string_lossy","into_path_buf","into_path_buf_lossy","into_string","into_string_lossy","into_string_unchecked","is_ascii","is_utf8","last_byte","lines","lines_with_terminator","make_ascii_lowercase","make_ascii_uppercase","new","new","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pop_byte","pop_char","prelude","push_byte","push_char","push_str","read","read","remove_char","repeatn","replace","replace_into","replace_range","replacen","replacen_into","reverse_bytes","reverse_chars","reverse_graphemes","rfind","rfind_byte","rfind_byteset","rfind_char","rfind_iter","rfind_not_byteset","rsplit_once_str","rsplit_str","rsplitn_str","sentence_indices","sentences","split_once_str","split_str","splitn_str","starts_with_str","tes3","tes4","to_ascii_lowercase","to_ascii_uppercase","to_lowercase","to_lowercase_into","to_os_str","to_os_str_lossy","to_owned","to_owned","to_owned","to_owned","to_path","to_path_lossy","to_str","to_str_lossy","to_str_lossy_into","to_str_unchecked","to_string","to_string","to_uppercase","to_uppercase_into","trim","trim_end","trim_end_with","trim_start","trim_start_with","trim_with","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","unescape_bytes","utf8_chunks","word_indices","words","words_with_break_indices","words_with_breaks","AlreadyCompressed","AlreadyDecompressed","Archive","ArchiveKey","ArchiveOptions","ArchiveOptionsBuilder","Chunk","ChunkCompressionOptions","ChunkCompressionOptionsBuilder","CompressionFormat","CompressionLevel","DX10","DX10","DX10","DX10Header","DecompressionSizeMismatch","Err","Error","FO4","FO4Xbox","FO76","File","FileCapacityError","FileHash","FileHeader","FileReadOptions","FileReadOptionsBuilder","FileWriteOptions","FileWriteOptionsBuilder","Format","FormatMismatch","GNMF","GNMF","GNMFHeader","GNRL","GNRL","Hash","IntegralOverflow","IntegralTruncation","InvalidChunkSentinel","InvalidChunkSize","InvalidFormat","InvalidMagic","InvalidVersion","Io","LZ4","LZ4","NotImplemented","Ok","Result","SF","Version","Zip","as_bytes","as_mut","as_mut_ptr","as_mut_slice","as_ptr","as_ptr","as_ref","as_slice","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","build","build","build","builder","builder","builder","builder","clear","clear","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","compress","compress_into","compression_format","compression_format","compression_format","compression_format","compression_format","compression_format","compression_format","compression_format","compression_level","compression_level","compression_level","compression_level","compression_result","compression_result","decompress","decompress_into","decompressed_len","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","deref","deref_mut","directory","drain","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","extension","file","flags","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","format","format","format","format","format","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_compressed","from_compressed","from_compressed","from_decompressed","from_decompressed","from_decompressed","from_iter","from_iter","get","get_key_value","get_mut","hash","hash_file","hash_file_in_place","header","height","index","index_mut","insert","insert","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_element","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_owned","is_compressed","is_decompressed","is_empty","is_empty","is_empty","is_full","iter","iter","iter_mut","iter_mut","keys","len","len","len","metadata","mip_chunk_height","mip_chunk_height","mip_chunk_width","mip_chunk_width","mip_count","mips","name","new","new","new","new","new","new","new","new","new","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","pop","push","read","read","read","read","read","read","read","read","remaining_capacity","remove","remove","remove_entry","retain_mut","source","strings","strings","swap_remove","tile_mode","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","truncate","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_insert","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_push","try_swap_remove","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","v1","v2","v3","values","values_mut","version","version","width","write","write","write","actual","expected","_","_","_","Archive","ArchiveKey","Err","Error","File","FileHash","Hash","IntegralTruncation","InvalidMagic","Io","Ok","Result","as_bytes","as_mut","as_ptr","as_ref","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clear","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","default","default","default","default","default","deref","deref_mut","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_iter","get","get_key_value","get_mut","hash","hash_file","hash_file_in_place","hi","insert","into","into","into","into","into","into","into_iter","into_iter","into_iter","into_owned","is_empty","is_empty","iter","iter_mut","keys","len","len","lo","name","new","new","new","new","numeric","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","read","read","read","read","read","read","read","read","remove","remove_entry","source","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","values","values_mut","write","write","AlreadyCompressed","AlreadyDecompressed","Archive","ArchiveFlags","ArchiveKey","ArchiveOptions","ArchiveOptionsBuilder","ArchiveTypes","COMPRESSED","CompressionCodec","DIRECTORY_STRINGS","DecompressionSizeMismatch","Directory","DirectoryHash","DirectoryKey","EMBEDDED_FILE_NAMES","Err","Error","FILE_STRINGS","FNV","FO3","FONTS","File","FileCompressionOptions","FileCompressionOptionsBuilder","FileHash","FileReadOptions","FileReadOptionsBuilder","Hash","IntegralOverflow","IntegralTruncation","InvalidHeaderSize","InvalidMagic","InvalidVersion","Io","LZ4","MENUS","MESHES","MISC","Normal","Ok","RETAIN_DIRECTORY_NAMES","RETAIN_FILE_NAMES","RETAIN_FILE_NAME_OFFSETS","RETAIN_STRINGS_DURING_STARTUP","Result","SHADERS","SOUNDS","SSE","TES4","TES5","TEXTURES","TREES","VOICES","Version","XBOX_ARCHIVE","XBOX_COMPRESSED","all","all","as_bytes","as_mut","as_mut","as_ptr","as_ref","as_ref","bitand","bitand","bitand_assign","bitand_assign","bitor","bitor","bitor_assign","bitor_assign","bits","bits","bits","bits","bitxor","bitxor","bitxor_assign","bitxor_assign","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","build","build","builder","builder","builder","clear","clear","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","cmp","cmp","complement","complement","compress","compress_into","compressed","compression_codec","compression_codec","compression_codec","compression_codec","compression_result","compression_result","contains","contains","crc","decompress","decompress_into","decompressed_len","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","deref","deref","deref_mut","deref_mut","difference","difference","directory_strings","embedded_file_names","empty","empty","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","extend","extend","file_strings","first","flags","flags","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fonts","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_bits","from_bits","from_bits_retain","from_bits_retain","from_bits_retain","from_bits_retain","from_bits_truncate","from_bits_truncate","from_compressed","from_compressed","from_compressed","from_decompressed","from_decompressed","from_decompressed","from_iter","from_iter","from_iter","from_iter","from_name","from_name","get","get","get_key_value","get_key_value","get_mut","get_mut","hash","hash","hash_directory","hash_directory_in_place","hash_file","hash_file_in_place","insert","insert","insert","insert","intersection","intersection","intersects","intersects","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_owned","is_all","is_all","is_compressed","is_decompressed","is_empty","is_empty","is_empty","is_empty","is_empty","iter","iter","iter","iter","iter_mut","iter_mut","iter_names","iter_names","keys","keys","last","last2","len","len","len","length","menus","meshes","misc","name","name","new","new","new","new","new","new","new","new","new","not","not","numeric","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","read","read","read","read","read","read","read","read","remove","remove","remove","remove","remove_entry","remove_entry","retain_directory_names","retain_file_name_offsets","retain_file_names","retain_strings_during_startup","set","set","shaders","sounds","source","sub","sub","sub_assign","sub_assign","symmetric_difference","symmetric_difference","textures","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","toggle","toggle","trees","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","types","types","union","union","v103","v104","v105","values","values","values_mut","values_mut","version","version","version","version","version","version","voices","write","write","xbox_archive","xbox_compressed","actual","expected"],"q":[[0,"ba2"],[287,"ba2::fo4"],[794,"ba2::fo4::Error"],[796,"ba2::prelude"],[799,"ba2::tes3"],[955,"ba2::tes4"],[1503,"ba2::tes4::Error"],[1505,"bstr::ext_slice"],[1506,"bstr::utf8"],[1507,"bstr::utf8"],[1508,"core::convert"],[1509,"alloc::vec"],[1510,"bstr::ext_vec"],[1511,"core::ops::range"],[1512,"alloc::borrow"],[1513,"alloc::string"],[1514,"bstr::escape_bytes"],[1515,"bstr::ext_slice"],[1516,"core::option"],[1517,"bstr::ext_slice"],[1518,"core::fmt"],[1519,"core::fmt"],[1520,"core::fmt"],[1521,"std::ffi::os_str"],[1522,"std::ffi::os_str"],[1523,"std::path"],[1524,"bstr::unicode::grapheme"],[1525,"core::hash"],[1526,"core::ops::range"],[1527,"bstr::unicode::sentence"],[1528,"bstr::utf8"],[1529,"bstr::unicode::word"],[1530,"lzzzz::common::error"],[1531,"directxtex::hresult"],[1532,"core::num::error"],[1533,"std::io::error"],[1534,"core::convert"],[1535,"core::borrow"],[1536,"std::fs"],[1537,"core::error"],[1538,"std::io"],[1539,"bitflags::iter"],[1540,"bitflags::iter"]],"d":["A wrapper for &[u8] that provides convenient string …","A wrapper for Vec<u8> that provides convenient string …","Makes a shallow copy of the input.","A trait that extends &[u8] with string oriented methods.","A trait that extends Vec<u8> with string oriented methods.","A trait that creates an optionally compressed container …","The data will finish in a compressed state.","Indicates whether the operation should finish by …","Makes a deep copy of the input.","The data will finish in a decompressed state.","","","","The file format for a given archive.","","","","A trait that enables reading from various sources.","A trait that enables reading from various sources, with …","","","Return this byte slice as a &BStr.","Return this byte slice as a &mut BStr.","","","","","","","","","","","","","","","","","","","","","","","","","","Returns an iterator over the bytes in this byte string.","Returns an iterator over the Unicode scalar values in this …","Returns an iterator over the Unicode scalar values in this …","","","","","","","","","Returns true if and only if this byte string contains the …","","","","","","","","","Creates a draining iterator that removes the specified …","Returns true if and only if this byte string has the given …","","","","","","","","","","","","","","","","","","","","","","","","","","Escapes this byte string into a sequence of char values.","Returns an iterator over the fields in a byte string, …","Returns an iterator over the fields in a byte string, …","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of the given …","Returns the index of the first occurrence of any of the …","Returns the index of the first occurrence of the given …","Returns an iterator of the non-overlapping occurrences of …","Returns the index of the first non-ASCII byte in this byte …","Returns the index of the first occurrence of a byte that …","","","","","","","Fallout 4","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Makes a compressed instance of Self using the given data.","Makes a decompressed instance of Self using the given data.","","","","","","","Create an immutable byte string from an OS string slice.","Lossily create a new byte string from an OS string slice.","Create a new byte string from an owned OS string.","Create an immutable byte string from a file path.","Create a new byte string from an owned file path.","Lossily create a new byte string from a file path.","Create a new owned byte string from the given byte slice.","Returns an iterator over the grapheme clusters in this …","Returns an iterator over the grapheme clusters in this …","Guesses the archive format for a given source.","","","","","","","","","","","","","","","","","Inserts the given codepoint into this Vec<u8> at a …","Inserts the given byte string into this byte string at a …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Converts this byte string into an OS string, in place.","Lossily converts this byte string into an OS string, in …","Converts this byte string into an owned file path, in …","Lossily converts this byte string into an owned file path, …","Converts a Vec<u8> into a String if and only if this byte …","Lossily converts a Vec<u8> into a String. If this byte …","Unsafely convert this byte string into a String, without …","Returns true if and only if every byte in this byte string …","Returns true if and only if the entire byte string is …","Returns the last byte in this byte string, if it’s …","An iterator over all lines in a byte string, without their …","An iterator over all lines in a byte string, including …","Convert this byte string to its lowercase ASCII equivalent …","Convert this byte string to its uppercase ASCII equivalent …","Directly creates a BStr slice from anything that can be …","Constructs a new BString from the given Vec.","","","","","","","","","","","","","","","","","","","","","Removes the last byte from this Vec<u8> and returns it.","Removes the last codepoint from this Vec<u8> and returns …","Convenience using statements for traits that are needed to …","Appends the given byte to the end of this byte string.","Appends the given char to the end of this byte string.","Appends the given slice to the end of this byte string. …","Reads an instance of Self::Item from the given source.","Reads an instance of Self::Item from the given source, …","Removes a char from this Vec<u8> at the given byte …","Create a new byte string by repeating this byte string n …","Replace all matches of the given needle with the given …","Replace all matches of the given needle with the given …","Removes the specified range in this byte string and …","Replace up to limit matches of the given needle with the …","Replace up to limit matches of the given needle with the …","Reverse the bytes in this string, in place.","Reverse the codepoints in this string, in place.","Reverse the graphemes in this string, in place.","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of the given …","Returns the index of the last occurrence of any of the …","Returns the index of the last occurrence of the given …","Returns an iterator of the non-overlapping occurrences of …","Returns the index of the last occurrence of a byte that is …","Split this byte string at the last occurrence of splitter.","Returns an iterator over substrings of this byte string, …","Returns an iterator of at most limit substrings of this …","Returns an iterator over the sentences in this byte string …","Returns an iterator over the sentences in this byte string.","Split this byte string at the first occurrence of splitter.","Returns an iterator over substrings of this byte string, …","Returns an iterator of at most limit substrings of this …","Returns true if and only if this byte string has the given …","TES III: Morrowind","TES IV: Oblivion","Returns a new Vec<u8> containing the ASCII lowercase …","Returns a new Vec<u8> containing the ASCII uppercase …","Returns a new Vec<u8> containing the lowercase equivalent …","Writes the lowercase equivalent of this byte string into …","Create an OS string slice from this byte string.","Lossily create an OS string slice from this byte string.","","","","","Create a path slice from this byte string.","Lossily create a path slice from this byte string.","Safely convert this byte string into a &str if it’s …","Convert this byte string to a valid UTF-8 string by …","Copy the contents of this byte string into the given owned …","Unsafely convert this byte string into a &str, without …","","","Returns a new Vec<u8> containing the uppercase equivalent …","Writes the uppercase equivalent of this byte string into …","Return a byte string slice with leading and trailing …","Return a byte string slice with trailing whitespace …","Return a byte string slice with trailing characters …","Return a byte string slice with leading whitespace removed.","Return a byte string slice with leading characters …","Return a byte string slice with leading and trailing …","","","","","","","","","","","","","","","","","Unescapes the given string into its raw bytes.","Iterate over chunks of valid UTF-8.","Returns an iterator over the words in this byte string …","Returns an iterator over the words in this byte string. If …","Returns an iterator over the words and their byte offsets …","Returns an iterator over the words in this byte string, …","","","Represents the FO4 revision of the ba2 format.","A key for indexing into the relevant mapping.","Info about the contents of the given archive.","See also ArchiveOptions.","Represents a chunk of a file within the FO4 virtual …","Common parameters to configure how chunks are compressed.","See also ChunkCompressionOptions.","A list of all compression methods supported by the ba2 …","Specifies the compression level to use when compressing …","","A DX10 archive can only contain .dds files (Microsoft …","","File header for DX10 archives.","","Contains the error value","","Fallout 4.","Fallout 4 on the xbox.","Fallout 76.","Represents a file within the FO4 virtual filesystem.","File is at chunk capacity.","See also Hash.","Optionally present file header.","Common parameters to configure how files are read.","See also FileReadOptions.","Common parameters to configure how files are written.","See also FileWriteOptions.","Represents the file format for an archive.","","A GNMF archive can only contain .gnf files (Sony GNM).","","File header for GNMF archives.","A GNRL archive can contain any kind of file.","","The underlying hash object used to uniquely identify …","","","","","","","","","","A more specialized format leveraging lz4’s fast …","","Contains the success value","","Starfield.","Indicates the version of an archive.","The default compression format, compatible with all games …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","The file’s parent path crc.","Panics","","","","","","","","","","","","","The first 4 bytes of the file’s extension.","The file’s stem crc.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","","","","Produces a hash using the given path.","Produces a hash using the given path.","","","","","Panics","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","See here for more info.","","","","","","","","","","","","","","","","","","","","","","","","Panics","","","","","","","","","","Panics","","","","","","","Panics","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Panics","","","","","","","","","","","","","","","","","","","","","","","","","Panics","","","","","","","","","","","","","","","","","","","","","","","","Initial format introduced in Fallout 4.","Intoduced in Starfield.","Intoduced in Starfield.","","","","","","","","","","","","","","Represents the TES3 revision of the bsa format.","A key for indexing into the relevant mapping.","Contains the error value","","Represents a file within the TES3 virtual filesystem.","See also Hash.","The underlying hash object used to uniquely identify …","","","","Contains the success value","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","Produces a hash using the given path.","Produces a hash using the given path.","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Represents the TES4 revision of the bsa format.","Archive flags can impact the layout of an archive, or how …","A key for indexing into the relevant mapping.","","See also ArchiveOptions.","Specifies file types contained within an archive.","Compresses the data within the archive.","Specifies the codec to use when performing …","Includes directory paths within the archive.","","Represents a directory within the TES4 virtual filesystem.","See also Hash.","A key for indexing into the relevant mapping.","Writes the full (virtual) path of a file next to the data …","Contains the error value","","Includes filenames within the archive.","Fallout: New Vegas.","Fallout 3.","","Represents a file within the TES4 virtual filesystem.","Common parameters to configure how files are …","See also FileCompressionOptions.","See also Hash.","Common parameters to configure how files are read.","See also FileReadOptions.","The underlying hash object used to uniquely identify …","","","","","","","","","","","The default compression codec.","Contains the success value","Impacts runtime parsing.","Impacts runtime parsing.","Impacts runtime parsing.","Impacts runtime parsing.","","","","The Elder Scrolls V: Skyrim - Special Edition.","The Elder Scrolls IV: Oblivion.","The Elder Scrolls V: Skyrim.","","","","The archive version.","Writes the archive in the xbox (big-endian) format.","Uses the xmem codec from XNA 4.0 to compress the archive.","Get a flags value with all known bits set.","Get a flags value with all known bits set.","","","","","","","The bitwise and (&) of the bits in two flags values.","The bitwise and (&) of the bits in two flags values.","The bitwise and (&) of the bits in two flags values.","The bitwise and (&) of the bits in two flags values.","The bitwise or (|) of the bits in two flags values.","The bitwise or (|) of the bits in two flags values.","The bitwise or (|) of the bits in two flags values.","The bitwise or (|) of the bits in two flags values.","Get the underlying bits value.","","","Get the underlying bits value.","The bitwise exclusive-or (^) of the bits in two flags …","The bitwise exclusive-or (^) of the bits in two flags …","The bitwise exclusive-or (^) of the bits in two flags …","The bitwise exclusive-or (^) of the bits in two flags …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","The bitwise negation (!) of the bits in a flags value, …","The bitwise negation (!) of the bits in a flags value, …","","","","","","","","","","Whether all set bits in a source flags value are also set …","Whether all set bits in a source flags value are also set …","","","","","","","","","","","","","","","","","","","","","","","","","","","The intersection of a source flags value with the …","The intersection of a source flags value with the …","","","Get a flags value with all bits unset.","Get a flags value with all bits unset.","","","","","","","","","","","","","","The bitwise or (|) of the bits in each flags value.","The bitwise or (|) of the bits in each flags value.","","The first character of the path (directory) or stem (file).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","","","","Returns the argument unchanged.","","","Returns the argument unchanged.","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Convert from a bits value.","Convert from a bits value.","","Convert from a bits value exactly.","","Convert from a bits value exactly.","Convert from a bits value, unsetting any unknown bits.","Convert from a bits value, unsetting any unknown bits.","","","","","","","","","The bitwise or (|) of the bits in each flags value.","The bitwise or (|) of the bits in each flags value.","Get a flags value with the bits of a flag with the given …","Get a flags value with the bits of a flag with the given …","","","","","","","","","Produces a hash using the given path.","Produces a hash using the given path.","Produces a hash using the given path.","Produces a hash using the given path.","","","The bitwise or (|) of the bits in two flags values.","The bitwise or (|) of the bits in two flags values.","The bitwise and (&) of the bits in two flags values.","The bitwise and (&) of the bits in two flags values.","Whether any set bits in a source flags value are also set …","Whether any set bits in a source flags value are also set …","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","Whether all known bits in this flags value are set.","Whether all known bits in this flags value are set.","","","","","","Whether all bits in this flags value are unset.","Whether all bits in this flags value are unset.","","","Yield a set of contained flags values.","Yield a set of contained flags values.","","","Yield a set of contained named flags values.","Yield a set of contained named flags values.","","","The last character of the path (directory) or stem (file).","The second to last character of the path (directory) or …","","","","The length of the path (directory) or stem (file).","","","","","","","","","","","","","","","The bitwise negation (!) of the bits in a flags value, …","The bitwise negation (!) of the bits in a flags value, …","","","","","","","","","","","","","","","","","","","","","","The intersection of a source flags value with the …","The intersection of a source flags value with the …","","","","","","","Call insert when value is true or remove when value is …","Call insert when value is true or remove when value is …","","","","The intersection of a source flags value with the …","The intersection of a source flags value with the …","The intersection of a source flags value with the …","The intersection of a source flags value with the …","The bitwise exclusive-or (^) of the bits in two flags …","The bitwise exclusive-or (^) of the bits in two flags …","","","","","","","","","","","","","","","","","","The bitwise exclusive-or (^) of the bits in two flags …","The bitwise exclusive-or (^) of the bits in two flags …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","The bitwise or (|) of the bits in two flags values.","The bitwise or (|) of the bits in two flags values.","","","","","","","","","","","","","","","","","","","",""],"i":[0,0,0,0,0,0,9,0,0,9,137,138,8,0,137,138,138,0,0,8,8,139,139,1,4,4,1,1,4,4,101,99,1,1,4,4,4,8,9,101,99,1,1,4,4,4,8,9,139,139,139,4,8,9,4,8,9,1,4,139,1,1,4,9,1,4,1,4,140,139,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,8,9,139,139,139,139,139,139,139,139,139,139,1,1,4,4,8,9,0,101,99,1,1,1,4,4,4,4,4,4,4,4,8,9,141,141,4,4,4,4,4,4,139,140,140,139,140,140,140,139,139,0,1,4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,140,140,101,99,4,8,9,140,140,140,140,140,140,140,139,139,139,139,139,139,139,1,4,1,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,140,140,0,140,140,140,137,138,140,139,139,139,140,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,0,0,139,139,139,139,139,139,1,4,8,9,139,139,139,139,139,139,1,4,139,139,139,139,139,139,139,139,101,99,4,8,9,101,99,4,8,9,101,99,1,4,8,9,140,139,139,139,139,139,90,90,0,0,0,0,0,0,0,0,0,90,82,84,0,90,87,0,81,81,81,0,0,0,0,0,0,0,0,0,90,82,84,0,82,84,0,90,90,90,90,90,90,90,90,90,80,90,87,0,81,0,80,66,67,69,69,69,66,67,69,89,90,80,81,82,83,67,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,70,78,77,89,90,80,81,82,83,67,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,78,77,71,73,75,77,72,74,76,78,69,79,80,81,82,83,67,68,69,84,85,86,72,74,66,76,79,70,78,77,80,81,82,83,67,68,69,84,85,86,72,74,66,76,79,70,78,77,83,67,68,70,66,66,72,71,74,73,76,75,78,77,74,73,76,75,74,73,66,66,66,80,81,82,83,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,78,77,67,67,68,69,80,81,82,83,67,67,68,68,84,85,86,70,68,68,86,89,89,90,90,80,81,82,83,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,78,77,74,73,78,77,86,89,90,90,90,90,90,90,80,81,82,83,67,67,68,68,69,84,84,84,85,86,72,72,72,71,71,71,74,74,74,73,73,73,66,76,76,76,75,75,75,79,70,70,70,78,77,66,66,66,66,66,66,69,79,79,79,79,70,0,0,69,86,69,69,69,79,89,90,80,81,82,83,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,78,77,89,69,69,69,79,79,79,66,66,66,69,66,79,69,69,79,69,79,79,69,66,79,85,74,73,74,73,86,66,70,67,68,69,71,73,66,75,79,77,83,67,67,68,68,70,69,69,69,69,69,69,79,79,79,79,69,69,79,79,69,90,78,77,69,86,80,81,82,83,67,68,69,84,85,86,72,74,66,76,79,70,78,77,89,90,69,89,90,80,81,82,83,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,78,77,69,89,90,80,81,82,83,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,78,77,69,69,89,90,80,81,82,83,67,68,69,84,85,86,72,71,74,73,66,76,75,79,70,78,77,83,83,83,79,79,78,77,86,69,66,79,142,142,0,0,0,0,0,111,0,0,0,0,109,109,109,111,0,104,105,104,105,109,105,105,106,104,108,107,107,109,105,105,106,104,108,107,108,105,106,104,108,107,105,106,104,108,107,105,106,107,105,106,104,108,107,105,105,105,105,106,106,107,109,109,105,106,104,108,107,109,109,109,105,105,106,106,104,104,104,104,108,107,107,107,108,108,108,108,107,0,0,106,108,109,105,106,104,108,107,108,108,108,104,104,108,108,108,108,104,108,106,107,105,106,104,108,106,105,105,106,106,107,104,104,104,104,108,108,108,108,108,108,109,105,106,104,108,107,109,109,105,106,104,108,107,109,105,106,104,108,107,109,105,106,104,108,107,108,108,104,108,133,133,0,0,0,0,0,0,113,0,113,133,0,0,0,113,132,0,113,131,131,112,0,0,0,0,0,0,0,133,133,133,133,133,133,133,112,112,112,130,132,113,113,113,113,0,112,112,131,131,131,112,112,112,0,113,113,112,113,114,115,117,114,115,117,112,113,112,113,112,113,112,113,112,112,113,113,112,113,112,113,133,130,131,115,115,117,117,116,114,123,122,125,124,128,120,120,129,127,126,121,121,112,113,133,130,131,115,115,117,117,116,114,123,122,125,124,128,120,129,127,126,121,112,113,122,124,126,123,125,127,128,129,130,131,115,117,116,114,123,125,128,120,129,127,121,112,113,130,131,115,117,116,114,123,125,128,120,129,127,121,112,113,131,115,117,116,120,121,112,113,114,114,113,123,122,125,124,123,122,112,113,116,114,114,114,130,131,115,117,116,114,123,122,125,124,128,120,129,127,126,121,112,113,115,117,115,117,112,113,113,113,112,113,130,131,115,115,117,117,116,116,116,120,121,112,113,112,113,113,116,127,126,133,133,130,131,115,117,116,114,123,122,125,124,128,120,129,127,126,121,112,112,112,112,112,113,113,113,113,113,112,133,133,133,133,130,131,115,115,117,117,116,116,116,114,123,123,123,122,122,122,125,125,125,124,124,124,128,120,120,120,129,127,126,121,121,121,112,113,112,113,112,112,113,113,112,113,114,114,114,114,114,114,128,129,112,113,112,113,128,129,128,129,128,129,120,121,0,0,0,0,128,129,112,113,112,113,112,113,133,130,131,115,117,116,114,123,122,125,124,128,120,129,127,126,121,112,113,128,128,128,129,129,129,112,113,114,112,113,114,114,114,128,129,112,113,128,129,112,113,128,129,112,113,128,129,116,116,114,128,129,116,112,112,112,120,121,115,117,116,114,122,124,128,129,126,112,113,116,131,115,115,117,117,116,116,116,120,121,114,114,114,114,129,129,129,129,128,129,112,113,128,129,113,113,113,113,112,113,112,112,133,112,113,112,113,112,113,112,130,131,115,117,116,114,123,125,128,120,129,127,121,112,113,133,112,113,112,133,130,131,115,117,116,114,123,122,125,124,128,120,129,127,126,121,112,113,133,130,131,115,117,116,114,123,122,125,124,128,120,129,127,126,121,112,113,133,130,131,115,117,116,114,123,122,125,124,128,120,129,127,126,121,112,113,127,126,112,113,131,131,131,128,129,128,129,123,122,125,124,127,126,112,114,129,113,113,143,143],"f":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[-1,1,[]],[-1,1,[]],[1,[[3,[2]]]],[4,1],[4,[[3,[2]]]],[1,1],[1,[[3,[2]]]],[4,1],[4,[[3,[2]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[1,[[3,[2]]]],[4,1],[-1,-2,[],[]],[4,[[3,[2]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[1,[[3,[2]]]],[-1,-2,[],[]],[4,[[3,[2]]]],[4,1],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,5,[]],[-1,6,[]],[-1,7,[]],[4,4],[8,8],[9,9],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[1,1],11],[[4,4],11],[[-1,-2],12,[],[[13,[[3,[2]]]]]],[[],1],[[],1],[[],4],[[],9],[1,[[3,[2]]]],[4,[[14,[2]]]],[1,[[3,[2]]]],[4,[[14,[2]]]],[[-1,-2],15,[],[[17,[16]]]],[[-1,-2],12,[],[[13,[[3,[2]]]]]],[[1,[18,[[3,[2]]]]],12],[[1,19],12],[[1,[18,[20]]],12],[[1,[3,[2]]],12],[[1,1],12],[[1,19],12],[[1,20],12],[[1,[14,[2]]],12],[[1,[14,[2]]],12],[[1,4],12],[[1,[3,[2]]],12],[[1,[18,[1]]],12],[[1,4],12],[[1,20],12],[[4,[14,[2]]],12],[[4,4],12],[[4,1],12],[[4,20],12],[[4,1],12],[[4,[3,[2]]],12],[[4,19],12],[[4,[3,[2]]],12],[[4,20],12],[[8,8],12],[[9,9],12],[-1,21,[]],[-1,22,[]],[[-1,-2],[[23,[-2]]],[],24],[[-1,-2],[[25,[16]]],[],[[13,[[3,[2]]]]]],[[-1,2],[[25,[16]]],[]],[[-1,-2],[[25,[16]]],[],[[13,[[3,[2]]]]]],[[-1,26],[[25,[16]]],[]],[[-1,-2],27,[],[[13,[[3,[2]]]],28]],[-1,[[25,[16]]],[]],[[-1,-2],[[25,[16]]],[],[[13,[[3,[2]]]]]],[[1,29],[[31,[10,30]]]],[[1,29],[[31,[10,30]]]],[[4,29],[[31,[10,30]]]],[[4,29],[[31,[10,30]]]],[[8,29],32],[[9,29],32],0,[-1,-1,[]],[-1,-1,[]],[20,1],[[[3,[2]]],1],[[[33,[2]]],1],[[[33,[2]]],4],[[[33,[2]]],4],[20,4],[1,4],[19,4],[[[14,[2]]],4],[[[3,[2]]],4],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[[-1,16],-2,[],[]],[-1,-2,[],[]],[-1,4,34],[-1,4,34],[-1,4,34],[-1,4,34],[-1,4,34],[-1,4,34],[35,[[25,[[3,[2]]]]]],[35,[[18,[[3,[2]]]]]],[36,[[31,[[14,[2]],36]]]],[37,[[25,[[3,[2]]]]]],[38,[[31,[[14,[2]],38]]]],[37,[[18,[[3,[2]]]]]],[-1,[[14,[2]]],[[13,[[3,[2]]]]]],[-1,39,[]],[-1,40,[]],[-1,[[25,[8]]],[28,41]],[[1,-1],10,42],[[4,-1],10,42],[[1,[43,[16]]],1],[[1,[44,[16]]],1],[[1,[45,[16]]],1],[[1,46],1],[[1,[47,[16]]],1],[[1,16],2],[[1,[48,[16]]],1],[[1,46],1],[[1,[45,[16]]],1],[[1,[43,[16]]],1],[[1,16],2],[[1,[48,[16]]],1],[[1,[44,[16]]],1],[[1,[47,[16]]],1],[[-1,16,26],10,[]],[[-1,16,-2],10,[],[[13,[[3,[2]]]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[31,[36,49]]],28],[-1,36,28],[-1,[[31,[38,49]]],28],[-1,38,28],[-1,[[31,[19,49]]],28],[-1,19,28],[-1,19,28],[-1,12,[]],[-1,12,[]],[-1,[[25,[2]]],[]],[-1,50,[]],[-1,51,[]],[-1,10,[]],[-1,10,[]],[-1,1,[[13,[[3,[2]]]],28]],[[[14,[2]]],4],[[1,[3,[2]]],[[25,[11]]]],[[1,[14,[2]]],[[25,[11]]]],[[1,4],[[25,[11]]]],[[1,1],[[25,[11]]]],[[1,[3,[2]]],[[25,[11]]]],[[1,[14,[2]]],[[25,[11]]]],[[1,19],[[25,[11]]]],[[1,20],[[25,[11]]]],[[1,20],[[25,[11]]]],[[1,4],[[25,[11]]]],[[1,19],[[25,[11]]]],[[4,19],[[25,[11]]]],[[4,[3,[2]]],[[25,[11]]]],[[4,[14,[2]]],[[25,[11]]]],[[4,20],[[25,[11]]]],[[4,20],[[25,[11]]]],[[4,4],[[25,[11]]]],[[4,1],[[25,[11]]]],[[4,1],[[25,[11]]]],[[4,[3,[2]]],[[25,[11]]]],[-1,[[25,[2]]],[]],[-1,[[25,[26]]],[]],0,[[-1,2],10,[]],[[-1,26],10,[]],[[-1,-2],10,[],[[13,[[3,[2]]]]]],[-1,31,[]],[-1,31,[]],[[-1,16],26,[]],[[-1,16],[[14,[2]]],[]],[[-1,-2,-3],[[14,[2]]],[],[[13,[[3,[2]]]]],[[13,[[3,[2]]]]]],[[-1,-2,-3,[14,[2]]],10,[],[[13,[[3,[2]]]]],[[13,[[3,[2]]]]]],[[-1,-2,-3],10,[],[[17,[16]]],[[13,[[3,[2]]]]]],[[-1,-2,-3,16],[[14,[2]]],[],[[13,[[3,[2]]]]],[[13,[[3,[2]]]]]],[[-1,-2,-3,16,[14,[2]]],10,[],[[13,[[3,[2]]]]],[[13,[[3,[2]]]]]],[-1,10,[]],[-1,10,[]],[-1,10,[]],[[-1,-2],[[25,[16]]],[],[[13,[[3,[2]]]]]],[[-1,2],[[25,[16]]],[]],[[-1,-2],[[25,[16]]],[],[[13,[[3,[2]]]]]],[[-1,26],[[25,[16]]],[]],[[-1,-2],52,[],[[13,[[3,[2]]]],28]],[[-1,-2],[[25,[16]]],[],[[13,[[3,[2]]]]]],[[-1,-2],[[25,[[10,[[3,[2]],[3,[2]]]]]]],[],[[13,[[3,[2]]]],28]],[[-1,-2],53,[],[[13,[[3,[2]]]],28]],[[-1,16,-2],54,[],[[13,[[3,[2]]]],28]],[-1,55,[]],[-1,56,[]],[[-1,-2],[[25,[[10,[[3,[2]],[3,[2]]]]]]],[],[[13,[[3,[2]]]],28]],[[-1,-2],57,[],[[13,[[3,[2]]]],28]],[[-1,16,-2],58,[],[[13,[[3,[2]]]],28]],[[-1,-2],12,[],[[13,[[3,[2]]]]]],0,0,[-1,[[14,[2]]],[]],[-1,[[14,[2]]],[]],[-1,[[14,[2]]],[]],[[-1,[14,[2]]],10,[]],[-1,[[31,[35,59]]],[]],[-1,[[18,[35]]],[]],[1,4],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,[[31,[37,59]]],[]],[-1,[[18,[37]]],[]],[-1,[[31,[20,59]]],[]],[-1,[[18,[20]]],[]],[[-1,19],10,[]],[-1,20,[]],[-1,19,[]],[-1,19,[]],[-1,[[14,[2]]],[]],[[-1,[14,[2]]],10,[]],[-1,[[3,[2]]],[]],[-1,[[3,[2]]],[]],[[-1,-2],[[3,[2]]],[],24],[-1,[[3,[2]]],[]],[[-1,-2],[[3,[2]]],[],24],[[-1,-2],[[3,[2]]],[],24],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,[[14,[2]]],[[13,[20]]]],[-1,61,[]],[-1,62,[]],[-1,63,[]],[-1,64,[]],[-1,65,[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[66,[[3,[2]]]],[67,68],[69,66],[69,[[3,[66]]]],[69,66],[66,2],[67,68],[69,[[3,[66]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[67,68],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[70,67],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[67,68],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[71,72],[73,74],[75,76],[77,78],[[],71],[[],73],[[],75],[[],77],[69,10],[79,10],[80,80],[81,81],[82,82],[83,83],[67,67],[68,68],[69,69],[84,84],[85,85],[86,86],[72,72],[74,74],[66,66],[76,76],[79,79],[70,70],[78,78],[77,77],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[83,83],11],[[67,67],11],[[68,68],11],[[70,70],11],[[66,76],[[87,[66]]]],[[66,[14,[2]],76],[[87,[10]]]],[72,80],[[71,80],71],[74,80],[[73,80],73],[76,80],[[75,80],75],[78,80],[[77,80],77],[74,81],[[73,81],73],[76,81],[[75,81],75],[74,9],[[73,9],73],[[66,76],[[87,[66]]]],[[66,[14,[2]],76],[[87,[10]]]],[66,[[25,[16]]]],[[],80],[[],81],[[],82],[[],83],[[],67],[[],68],[[],69],[[],84],[[],85],[[],86],[[],72],[[],71],[[],74],[[],73],[[],66],[[],76],[[],75],[[],79],[[],70],[[],78],[[],77],[67],[67],0,[[69,-1],[[0,[88]]],[[17,[16]]]],[[80,80],12],[[81,81],12],[[82,82],12],[[83,83],12],[[67,67],12],[[67,68],12],[[68,67],12],[[68,68],12],[[84,84],12],[[85,85],12],[[86,86],12],[[70,70],12],0,0,0,[[89,29],32],[[89,29],32],[[90,29],32],[[90,29],32],[[80,29],32],[[81,29],32],[[82,29],32],[[83,29],32],[[67,29],32],[[68,29],32],[[69,29],32],[[84,29],32],[[85,29],32],[[86,29],32],[[72,29],32],[[71,29],32],[[74,29],32],[[73,29],32],[[66,29],32],[[76,29],32],[[75,29],32],[[79,29],32],[[70,29],32],[[78,29],32],[[77,29],32],[74,82],[[73,82],73],[78,82],[[77,82],77],0,[-1,-1,[]],[-1,-1,[]],[91,90],[92,90],[93,90],[94,90],[95,90],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[68,67],[-1,-1,[]],[67,68],[-1,-1,[]],[-1,-1,[]],[86,84],[85,84],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[78,72],[78,72],[78,71],[78,71],[-1,-1,[]],[-1,-1,[]],[78,74],[78,74],[78,73],[78,73],[-1,-1,[]],[-1,-1,[]],[78,76],[78,76],[-1,-1,[]],[-1,-1,[]],[78,75],[78,75],[-1,-1,[]],[67,70],[-1,-1,[]],[-1,70,[[96,[4]]]],[-1,-1,[]],[-1,-1,[]],[[[97,[[3,[2]]]],16],66],[[[3,[2]],16],66],[[[33,[2]],16],66],[[[3,[2]]],66],[[[97,[[3,[2]]]]],66],[[[33,[2]]],66],[-1,69,34],[-1,79,34],[[79,-1],[[25,[69]]],[[98,[67]]]],[[79,-1],[[25,[[10,[70,69]]]]],[[98,[67]]]],[[79,-1],[[25,[69]]],[[98,[67]]]],[70,67],[1,[[10,[67,4]]]],[4,67],0,0,[[69,16]],[[69,16]],[[69,16,66],10],[[79,-1,69],[[25,[69]]],[[96,[70]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[89,66],[69],[69],[69],[79],[79],[79],[66,66],[66,12],[66,12],[69,12],[66,12],[79,12],[69,12],[69,[[0,[88]]]],[79,[[0,[88]]]],[69,[[0,[88]]]],[79,[[0,[88]]]],[79,[[0,[88]]]],[69,16],[66,16],[79,16],0,[74,16],[[73,16],73],[74,16],[[73,16],73],0,0,[70,1],[[],67],[[],68],[[],69],[[],71],[[],73],[[],66],[[],75],[[],79],[[],77],[[83,83],[[25,[11]]]],[[67,68],[[25,[11]]]],[[67,67],[[25,[11]]]],[[68,68],[[25,[11]]]],[[68,67],[[25,[11]]]],[[70,70],[[25,[11]]]],[69,[[25,[66]]]],[[69,66],10],[99,87],[100,87],[37,87],[101,87],[100,87],[101,87],[99,87],[37,87],[69,16],[[69,16],66],[[79,-1],[[25,[69]]],[[98,[67]]]],[[79,-1],[[25,[[10,[70,69]]]]],[[98,[67]]]],[[69,-1],10,24],[90,[[25,[102]]]],[78,12],[[77,12],77],[[69,16],66],0,[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,19,[]],[-1,19,[]],[[69,16],10],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[[69,16,66],[[31,[10,89]]]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[[69,66],[[31,[10,89]]]],[[69,16],[[25,[66]]]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],0,0,0,[79,[[0,[88]]]],[79,[[0,[88]]]],[78,83],[[77,83],77],0,[[69,-1,72],[[87,[10]]],[28,103]],[[66,-1,76],[[87,[10]]],[28,103]],[[79,-1,78],[[87,[10]]],[28,103]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[104,[[3,[2]]]],[105,106],[104,2],[105,106],[-1,-2,[],[]],[-1,-2,[],[]],[105,106],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[107,105],[-1,-2,[],[]],[-1,-2,[],[]],[105,106],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[108,10],[105,105],[106,106],[104,104],[108,108],[107,107],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[105,105],11],[[106,106],11],[[107,107],11],[[],105],[[],106],[[],104],[[],108],[[],107],[105],[105],[[105,105],12],[[105,106],12],[[106,105],12],[[106,106],12],[[107,107],12],[[109,29],32],[[109,29],32],[[105,29],32],[[106,29],32],[[104,29],32],[[108,29],32],[[107,29],32],[93,109],[94,109],[-1,-1,[]],[106,105],[-1,-1,[]],[105,106],[-1,-1,[]],[[[97,[[3,[2]]]]],104],[-1,-1,[]],[[[3,[2]]],104],[[[33,[2]]],104],[-1,-1,[]],[-1,-1,[]],[-1,107,[[96,[4]]]],[105,107],[-1,108,34],[[108,-1],[[25,[104]]],[[98,[105]]]],[[108,-1],[[25,[[10,[107,104]]]]],[[98,[105]]]],[[108,-1],[[25,[104]]],[[98,[105]]]],[107,105],[1,[[10,[105,4]]]],[4,105],0,[[108,-1,104],[[25,[104]]],[[96,[107]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[108],[108],[108],[104,104],[104,12],[108,12],[108,[[0,[88]]]],[108,[[0,[88]]]],[108,[[0,[88]]]],[104,16],[108,16],0,[107,1],[[],105],[[],106],[[],104],[[],108],[106,110],[[105,106],[[25,[11]]]],[[105,105],[[25,[11]]]],[[106,106],[[25,[11]]]],[[106,105],[[25,[11]]]],[[107,107],[[25,[11]]]],[100,111],[99,111],[37,111],[101,111],[101,111],[100,111],[37,111],[99,111],[[108,-1],[[25,[104]]],[[98,[105]]]],[[108,-1],[[25,[[10,[107,104]]]]],[[98,[105]]]],[109,[[25,[102]]]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,19,[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[108,[[0,[88]]]],[108,[[0,[88]]]],[[104,-1],[[111,[10]]],[28,103]],[[108,-1],[[111,[10]]],[28,103]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[],112],[[],113],[114,[[3,[2]]]],[115,116],[117,116],[114,2],[115,116],[117,116],[[112,112],112],[[113,113],113],[[112,112],10],[[113,113],10],[[112,112],112],[[113,113],113],[[112,112],10],[[113,113],10],[112,118],[112,118],[113,119],[113,119],[[112,112],112],[[113,113],113],[[112,112],10],[[113,113],10],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[115,116],[-1,-2,[],[]],[-1,-2,[],[]],[117,116],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[120,115],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[121,117],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[115,116],[-1,-2,[],[]],[117,116],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[122,123],[124,125],[126,127],[[],122],[[],124],[[],126],[128,10],[129,10],[130,130],[131,131],[115,115],[117,117],[116,116],[114,114],[123,123],[125,125],[128,128],[120,120],[129,129],[127,127],[121,121],[112,112],[113,113],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[-1,-2],10,[],[]],[[131,131],11],[[115,115],11],[[117,117],11],[[116,116],11],[[120,120],11],[[121,121],11],[112,112],[113,113],[[114,125],[[132,[114]]]],[[114,[14,[2]],125],[[132,[10]]]],[113,12],[123,130],[[122,130],122],[125,130],[[124,130],124],[123,9],[[122,9],122],[[112,112],12],[[113,113],12],0,[[114,125],[[132,[114]]]],[[114,[14,[2]],125],[[132,[10]]]],[114,[[25,[16]]]],[[],130],[[],131],[[],115],[[],117],[[],116],[[],114],[[],123],[[],122],[[],125],[[],124],[[],128],[[],120],[[],129],[[],127],[[],126],[[],121],[[],112],[[],113],[115],[117],[115],[117],[[112,112],112],[[113,113],113],[113,12],[113,12],[[],112],[[],113],[[130,130],12],[[131,131],12],[[115,116],12],[[115,115],12],[[117,116],12],[[117,117],12],[[116,116],12],[[116,115],12],[[116,117],12],[[120,120],12],[[121,121],12],[[112,112],12],[[113,113],12],[[112,-1],10,34],[[113,-1],10,34],[113,12],0,[127,113],[[126,113],126],[[133,29],32],[[133,29],32],[[130,29],32],[[131,29],32],[[115,29],32],[[117,29],32],[[116,29],32],[[114,29],32],[[123,29],32],[[122,29],32],[[125,29],32],[[124,29],32],[[128,29],32],[[120,29],32],[[129,29],32],[[127,29],32],[[126,29],32],[[121,29],32],[[112,29],32],[[112,29],32],[[112,29],32],[[112,29],32],[[112,29],32],[[113,29],32],[[113,29],32],[[113,29],32],[[113,29],32],[[113,29],32],[112,12],[94,133],[93,133],[134,133],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[116,115],[-1,-1,[]],[116,117],[-1,-1,[]],[117,116],[115,116],[-1,-1,[]],[-1,-1,[]],[127,123],[127,123],[127,122],[-1,-1,[]],[127,122],[127,125],[-1,-1,[]],[127,125],[127,124],[127,124],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[-1,120,[[96,[4]]]],[115,120],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[117,121],[-1,121,[[96,[4]]]],[-1,-1,[]],[-1,-1,[]],[-1,-1,[]],[118,[[25,[112]]]],[119,[[25,[113]]]],[118,112],[118,112],[119,113],[119,113],[118,112],[119,113],[[[3,[2]],16],114],[[[33,[2]],16],114],[[[97,[[3,[2]]]],16],114],[[[33,[2]]],114],[[[3,[2]]],114],[[[97,[[3,[2]]]]],114],[-1,128,34],[-1,129,34],[-1,112,34],[-1,113,34],[20,[[25,[112]]]],[20,[[25,[113]]]],[[128,-1],[[25,[114]]],[[98,[115]]]],[[129,-1],[[25,[128]]],[[98,[117]]]],[[128,-1],[[25,[[10,[120,114]]]]],[[98,[115]]]],[[129,-1],[[25,[[10,[121,128]]]]],[[98,[117]]]],[[128,-1],[[25,[114]]],[[98,[115]]]],[[129,-1],[[25,[128]]],[[98,[117]]]],[120,115],[121,117],[1,[[10,[117,4]]]],[4,117],[1,[[10,[115,4]]]],[4,115],[[128,-1,114],[[25,[114]]],[[96,[120]]]],[[129,-1,128],[[25,[128]]],[[96,[121]]]],[[112,112],10],[[113,113],10],[[112,112],112],[[113,113],113],[[112,112],12],[[113,113],12],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[128],[128],[128],[129],[129],[129],[112],[113],[114,114],[112,12],[113,12],[114,12],[114,12],[114,12],[128,12],[129,12],[112,12],[113,12],[128,[[0,[88]]]],[129,[[0,[88]]]],[112,[[135,[112]]]],[113,[[135,[113]]]],[128,[[0,[88]]]],[129,[[0,[88]]]],[112,[[136,[112]]]],[113,[[136,[113]]]],[128,[[0,[88]]]],[129,[[0,[88]]]],0,0,[114,16],[128,16],[129,16],0,[112,12],[112,12],[112,12],[120,1],[121,1],[[],115],[[],117],[[],116],[[],114],[[],122],[[],124],[[],128],[[],129],[[],126],[112,112],[113,113],[116,110],[[131,131],[[25,[11]]]],[[115,115],[[25,[11]]]],[[115,116],[[25,[11]]]],[[117,117],[[25,[11]]]],[[117,116],[[25,[11]]]],[[116,117],[[25,[11]]]],[[116,115],[[25,[11]]]],[[116,116],[[25,[11]]]],[[120,120],[[25,[11]]]],[[121,121],[[25,[11]]]],[37,132],[100,132],[101,132],[99,132],[37,132],[99,132],[101,132],[100,132],[[128,-1],[[25,[114]]],[[98,[115]]]],[[129,-1],[[25,[128]]],[[98,[117]]]],[[112,112],10],[[113,113],10],[[128,-1],[[25,[[10,[120,114]]]]],[[98,[115]]]],[[129,-1],[[25,[[10,[121,128]]]]],[[98,[117]]]],[113,12],[113,12],[113,12],[113,12],[[112,112,12],10],[[113,113,12],10],[112,12],[112,12],[133,[[25,[102]]]],[[112,112],112],[[113,113],113],[[112,112],10],[[113,113],10],[[112,112],112],[[113,113],113],[112,12],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,-2,[],[]],[-1,19,[]],[[112,112],10],[[113,113],10],[112,12],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,[[31,[-2]]],[],[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[-1,60,[]],[127,112],[[126,112],126],[[112,112],112],[[113,113],113],0,0,0,[128,[[0,[88]]]],[129,[[0,[88]]]],[128,[[0,[88]]]],[129,[[0,[88]]]],[123,131],[[122,131],122],[125,131],[[124,131],124],[127,131],[[126,131],126],[112,12],[[114,-1,125],[[132,[10]]],[28,103]],[[129,-1,127],[[132,[10]]],[28,103]],[113,12],[113,12],0,0],"c":[],"p":[[3,"BStr",0],[15,"u8"],[15,"slice"],[3,"BString",0],[3,"Bytes",1505],[3,"CharIndices",1506],[3,"Chars",1506],[4,"FileFormat",0],[4,"CompressionResult",0],[15,"tuple"],[4,"Ordering",1507],[15,"bool"],[8,"AsRef",1508],[3,"Vec",1509],[3,"DrainBytes",1510],[15,"usize"],[8,"RangeBounds",1511],[4,"Cow",1512],[3,"String",1513],[15,"str"],[3,"EscapeBytes",1514],[3,"Fields",1505],[3,"FieldsWith",1505],[8,"FnMut",1515],[4,"Option",1516],[15,"char"],[3,"Find",1505],[8,"Sized",1517],[3,"Formatter",1518],[3,"Error",1518],[4,"Result",1519],[6,"Result",1518],[15,"array"],[8,"IntoIterator",1520],[3,"OsStr",1521],[3,"OsString",1521],[3,"Path",1522],[3,"PathBuf",1522],[3,"GraphemeIndices",1523],[3,"Graphemes",1523],[8,"Read",1524],[8,"Hasher",1525],[3,"RangeFrom",1511],[3,"RangeInclusive",1511],[3,"Range",1511],[3,"RangeFull",1511],[3,"RangeTo",1511],[3,"RangeToInclusive",1511],[3,"FromUtf8Error",1510],[3,"Lines",1505],[3,"LinesWithTerminator",1505],[3,"FindReverse",1505],[3,"SplitReverse",1505],[3,"SplitNReverse",1505],[3,"SentenceIndices",1526],[3,"Sentences",1526],[3,"Split",1505],[3,"SplitN",1505],[3,"Utf8Error",1506],[3,"TypeId",1527],[3,"Utf8Chunks",1506],[3,"WordIndices",1528],[3,"Words",1528],[3,"WordsWithBreakIndices",1528],[3,"WordsWithBreaks",1528],[3,"Chunk",287],[3,"FileHash",287],[3,"Hash",287],[3,"File",287],[3,"ArchiveKey",287],[3,"FileWriteOptionsBuilder",287],[3,"FileWriteOptions",287],[3,"FileReadOptionsBuilder",287],[3,"FileReadOptions",287],[3,"ChunkCompressionOptionsBuilder",287],[3,"ChunkCompressionOptions",287],[3,"ArchiveOptionsBuilder",287],[3,"ArchiveOptions",287],[3,"Archive",287],[4,"CompressionFormat",287],[4,"CompressionLevel",287],[4,"Format",287],[4,"Version",287],[4,"FileHeader",287],[3,"GNMFHeader",287],[3,"DX10Header",287],[6,"Result",287],[8,"Iterator",1529],[3,"FileCapacityError",287],[4,"Error",287],[3,"Error",1530],[3,"HResultError",1531],[3,"TryFromIntError",1532],[3,"Error",1533],[4,"Infallible",1508],[8,"Into",1508],[3,"Box",1534],[8,"Borrow",1535],[3,"Copied",0],[3,"File",1536],[3,"Borrowed",0],[8,"Error",1537],[8,"Write",1524],[3,"File",799],[3,"FileHash",799],[3,"Hash",799],[3,"ArchiveKey",799],[3,"Archive",799],[4,"Error",799],[15,"u64"],[6,"Result",799],[3,"ArchiveTypes",955],[3,"ArchiveFlags",955],[3,"File",955],[3,"FileHash",955],[3,"Hash",955],[3,"DirectoryHash",955],[15,"u16"],[15,"u32"],[3,"DirectoryKey",955],[3,"ArchiveKey",955],[3,"FileReadOptionsBuilder",955],[3,"FileReadOptions",955],[3,"FileCompressionOptionsBuilder",955],[3,"FileCompressionOptions",955],[3,"ArchiveOptionsBuilder",955],[3,"ArchiveOptions",955],[3,"Directory",955],[3,"Archive",955],[4,"CompressionCodec",955],[4,"Version",955],[6,"Result",955],[4,"Error",955],[4,"Error",1538],[3,"Iter",1539],[3,"IterNames",1539],[8,"Reader",0],[8,"ReaderWithOptions",0],[8,"ByteSlice",0],[8,"ByteVec",0],[8,"CompressableFrom",0],[13,"DecompressionSizeMismatch",794],[13,"DecompressionSizeMismatch",1503]],"b":[[24,"impl-AsMut%3CBStr%3E-for-BString"],[25,"impl-AsMut%3C%5Bu8%5D%3E-for-BString"],[26,"impl-AsRef%3CBStr%3E-for-BStr"],[27,"impl-AsRef%3C%5Bu8%5D%3E-for-BStr"],[28,"impl-AsRef%3CBStr%3E-for-BString"],[29,"impl-AsRef%3C%5Bu8%5D%3E-for-BString"],[34,"impl-Borrow%3CBStr%3E-for-BString"],[36,"impl-Borrow%3C%5Bu8%5D%3E-for-BString"],[43,"impl-BorrowMut%3C%5Bu8%5D%3E-for-BString"],[44,"impl-BorrowMut%3CBStr%3E-for-BString"],[60,"impl-Default-for-%26mut+BStr"],[61,"impl-Default-for-%26BStr"],[70,"impl-PartialEq%3CCow%3C\'a,+%5Bu8%5D%3E%3E-for-%26BStr"],[71,"impl-PartialEq%3CString%3E-for-BStr"],[72,"impl-PartialEq%3CCow%3C\'a,+str%3E%3E-for-%26BStr"],[73,"impl-PartialEq%3C%5Bu8%5D%3E-for-BStr"],[74,"impl-PartialEq-for-BStr"],[75,"impl-PartialEq%3CString%3E-for-%26BStr"],[76,"impl-PartialEq%3C%26str%3E-for-BStr"],[77,"impl-PartialEq%3CVec%3Cu8%3E%3E-for-BStr"],[78,"impl-PartialEq%3CVec%3Cu8%3E%3E-for-%26BStr"],[79,"impl-PartialEq%3CBString%3E-for-%26BStr"],[80,"impl-PartialEq%3C%26%5Bu8%5D%3E-for-BStr"],[81,"impl-PartialEq%3CCow%3C\'a,+BStr%3E%3E-for-%26BStr"],[82,"impl-PartialEq%3CBString%3E-for-BStr"],[83,"impl-PartialEq%3Cstr%3E-for-BStr"],[84,"impl-PartialEq%3CVec%3Cu8%3E%3E-for-BString"],[85,"impl-PartialEq-for-BString"],[86,"impl-PartialEq%3C%26BStr%3E-for-BString"],[87,"impl-PartialEq%3C%26str%3E-for-BString"],[88,"impl-PartialEq%3CBStr%3E-for-BString"],[89,"impl-PartialEq%3C%5Bu8%5D%3E-for-BString"],[90,"impl-PartialEq%3CString%3E-for-BString"],[91,"impl-PartialEq%3C%26%5Bu8%5D%3E-for-BString"],[92,"impl-PartialEq%3Cstr%3E-for-BString"],[105,"impl-Debug-for-BStr"],[106,"impl-Display-for-BStr"],[107,"impl-Display-for-BString"],[108,"impl-Debug-for-BString"],[114,"impl-From%3C%26str%3E-for-%26BStr"],[115,"impl-From%3C%26%5Bu8%5D%3E-for-%26BStr"],[116,"impl-From%3C%26%5Bu8;+N%5D%3E-for-%26BStr"],[117,"impl-From%3C%5Bu8;+N%5D%3E-for-BString"],[118,"impl-From%3C%26%5Bu8;+N%5D%3E-for-BString"],[119,"impl-From%3C%26str%3E-for-BString"],[120,"impl-From%3C%26BStr%3E-for-BString"],[121,"impl-From%3CString%3E-for-BString"],[122,"impl-From%3CVec%3Cu8%3E%3E-for-BString"],[123,"impl-From%3C%26%5Bu8%5D%3E-for-BString"],[129,"impl-FromIterator%3C%26BStr%3E-for-BString"],[130,"impl-FromIterator%3Cchar%3E-for-BString"],[131,"impl-FromIterator%3C%26%5Bu8%5D%3E-for-BString"],[132,"impl-FromIterator%3CBString%3E-for-BString"],[133,"impl-FromIterator%3C%26str%3E-for-BString"],[134,"impl-FromIterator%3Cu8%3E-for-BString"],[147,"impl-Index%3CRangeFrom%3Cusize%3E%3E-for-BStr"],[148,"impl-Index%3CRangeInclusive%3Cusize%3E%3E-for-BStr"],[149,"impl-Index%3CRange%3Cusize%3E%3E-for-BStr"],[150,"impl-Index%3CRangeFull%3E-for-BStr"],[151,"impl-Index%3CRangeTo%3Cusize%3E%3E-for-BStr"],[152,"impl-Index%3Cusize%3E-for-BStr"],[153,"impl-Index%3CRangeToInclusive%3Cusize%3E%3E-for-BStr"],[154,"impl-IndexMut%3CRangeFull%3E-for-BStr"],[155,"impl-IndexMut%3CRange%3Cusize%3E%3E-for-BStr"],[156,"impl-IndexMut%3CRangeFrom%3Cusize%3E%3E-for-BStr"],[157,"impl-IndexMut%3Cusize%3E-for-BStr"],[158,"impl-IndexMut%3CRangeToInclusive%3Cusize%3E%3E-for-BStr"],[159,"impl-IndexMut%3CRangeInclusive%3Cusize%3E%3E-for-BStr"],[160,"impl-IndexMut%3CRangeTo%3Cusize%3E%3E-for-BStr"],[184,"impl-PartialOrd%3C%26%5Bu8%5D%3E-for-BStr"],[185,"impl-PartialOrd%3CVec%3Cu8%3E%3E-for-%26BStr"],[186,"impl-PartialOrd%3CBString%3E-for-%26BStr"],[187,"impl-PartialOrd-for-BStr"],[188,"impl-PartialOrd%3C%5Bu8%5D%3E-for-BStr"],[189,"impl-PartialOrd%3CVec%3Cu8%3E%3E-for-BStr"],[190,"impl-PartialOrd%3CString%3E-for-%26BStr"],[191,"impl-PartialOrd%3Cstr%3E-for-BStr"],[192,"impl-PartialOrd%3C%26str%3E-for-BStr"],[193,"impl-PartialOrd%3CBString%3E-for-BStr"],[194,"impl-PartialOrd%3CString%3E-for-BStr"],[195,"impl-PartialOrd%3CString%3E-for-BString"],[196,"impl-PartialOrd%3C%5Bu8%5D%3E-for-BString"],[197,"impl-PartialOrd%3CVec%3Cu8%3E%3E-for-BString"],[198,"impl-PartialOrd%3Cstr%3E-for-BString"],[199,"impl-PartialOrd%3C%26str%3E-for-BString"],[200,"impl-PartialOrd-for-BString"],[201,"impl-PartialOrd%3C%26BStr%3E-for-BString"],[202,"impl-PartialOrd%3CBStr%3E-for-BString"],[203,"impl-PartialOrd%3C%26%5Bu8%5D%3E-for-BString"],[495,"impl-PartialEq-for-FileHash"],[496,"impl-PartialEq%3CHash%3E-for-FileHash"],[497,"impl-PartialEq%3CFileHash%3E-for-Hash"],[498,"impl-PartialEq-for-Hash"],[506,"impl-Debug-for-CapacityError%3C\'bytes%3E"],[507,"impl-Display-for-CapacityError%3C\'bytes%3E"],[508,"impl-Debug-for-Error"],[509,"impl-Display-for-Error"],[538,"impl-From%3CError%3E-for-Error"],[539,"impl-From%3CHResultError%3E-for-Error"],[540,"impl-From%3CTryFromIntError%3E-for-Error"],[541,"impl-From%3CError%3E-for-Error"],[542,"impl-From%3CInfallible%3E-for-Error"],[553,"impl-From%3CDX10%3E-for-Header"],[554,"impl-From%3CGNMF%3E-for-Header"],[558,"impl-From%3C%26Options%3E-for-WriteOptions"],[559,"impl-From%3COptions%3E-for-WriteOptions"],[560,"impl-From%3C%26Options%3E-for-WriteOptionsBuilder"],[561,"impl-From%3COptions%3E-for-WriteOptionsBuilder"],[564,"impl-From%3C%26Options%3E-for-ReadOptions"],[565,"impl-From%3COptions%3E-for-ReadOptions"],[566,"impl-From%3C%26Options%3E-for-ReadOptionsBuilder"],[567,"impl-From%3COptions%3E-for-ReadOptionsBuilder"],[570,"impl-From%3C%26Options%3E-for-CompressionOptions"],[571,"impl-From%3COptions%3E-for-CompressionOptions"],[574,"impl-From%3C%26Options%3E-for-CompressionOptionsBuilder"],[575,"impl-From%3COptions%3E-for-CompressionOptionsBuilder"],[577,"impl-From%3CFileHash%3E-for-Key%3C\'static%3E"],[579,"impl-From%3CT%3E-for-Key%3C\'static%3E"],[582,"impl-CompressableFrom%3CBox%3C%5Bu8%5D%3E%3E-for-Chunk%3C\'static%3E"],[583,"impl-CompressableFrom%3C%26%5Bu8%5D%3E-for-Chunk%3C\'bytes%3E"],[584,"impl-CompressableFrom%3C%26%5Bu8;+N%5D%3E-for-Chunk%3C\'bytes%3E"],[585,"impl-CompressableFrom%3C%26%5Bu8%5D%3E-for-Chunk%3C\'bytes%3E"],[586,"impl-CompressableFrom%3CBox%3C%5Bu8%5D%3E%3E-for-Chunk%3C\'static%3E"],[587,"impl-CompressableFrom%3C%26%5Bu8;+N%5D%3E-for-Chunk%3C\'bytes%3E"],[626,"impl-IntoIterator-for-%26File%3C\'bytes%3E"],[627,"impl-IntoIterator-for-File%3C\'bytes%3E"],[628,"impl-IntoIterator-for-%26mut+File%3C\'bytes%3E"],[629,"impl-IntoIterator-for-Archive%3C\'bytes%3E"],[630,"impl-IntoIterator-for-%26mut+Archive%3C\'bytes%3E"],[631,"impl-IntoIterator-for-%26Archive%3C\'bytes%3E"],[665,"impl-PartialOrd%3CHash%3E-for-FileHash"],[666,"impl-PartialOrd-for-FileHash"],[667,"impl-PartialOrd-for-Hash"],[668,"impl-PartialOrd%3CFileHash%3E-for-Hash"],[672,"impl-ReaderWithOptions%3CCopied%3C\'bytes%3E%3E-for-File%3C\'static%3E"],[673,"impl-ReaderWithOptions%3C%26File%3E-for-File%3C\'static%3E"],[674,"impl-ReaderWithOptions%3C%26Path%3E-for-File%3C\'static%3E"],[675,"impl-ReaderWithOptions%3CBorrowed%3C\'bytes%3E%3E-for-File%3C\'bytes%3E"],[676,"impl-Reader%3C%26File%3E-for-Archive%3C\'static%3E"],[677,"impl-Reader%3CBorrowed%3C\'bytes%3E%3E-for-Archive%3C\'bytes%3E"],[678,"impl-Reader%3CCopied%3C\'bytes%3E%3E-for-Archive%3C\'static%3E"],[679,"impl-Reader%3C%26Path%3E-for-Archive%3C\'static%3E"],[851,"impl-PartialEq-for-FileHash"],[852,"impl-PartialEq%3CHash%3E-for-FileHash"],[853,"impl-PartialEq%3CFileHash%3E-for-Hash"],[854,"impl-PartialEq-for-Hash"],[856,"impl-Display-for-Error"],[857,"impl-Debug-for-Error"],[863,"impl-From%3CTryFromIntError%3E-for-Error"],[864,"impl-From%3CError%3E-for-Error"],[870,"impl-From%3CBox%3C%5Bu8%5D%3E%3E-for-File%3C\'static%3E"],[872,"impl-From%3C%26%5Bu8%5D%3E-for-File%3C\'bytes%3E"],[873,"impl-From%3C%26%5Bu8;+N%5D%3E-for-File%3C\'bytes%3E"],[876,"impl-From%3CT%3E-for-Key%3C\'static%3E"],[877,"impl-From%3CFileHash%3E-for-Key%3C\'static%3E"],[893,"impl-IntoIterator-for-%26mut+Archive%3C\'bytes%3E"],[894,"impl-IntoIterator-for-Archive%3C\'bytes%3E"],[895,"impl-IntoIterator-for-%26Archive%3C\'bytes%3E"],[911,"impl-PartialOrd%3CHash%3E-for-FileHash"],[912,"impl-PartialOrd-for-FileHash"],[913,"impl-PartialOrd-for-Hash"],[914,"impl-PartialOrd%3CFileHash%3E-for-Hash"],[916,"impl-Reader%3C%26File%3E-for-File%3C\'static%3E"],[917,"impl-Reader%3CCopied%3C\'bytes%3E%3E-for-File%3C\'static%3E"],[918,"impl-Reader%3C%26Path%3E-for-File%3C\'static%3E"],[919,"impl-Reader%3CBorrowed%3C\'bytes%3E%3E-for-File%3C\'bytes%3E"],[920,"impl-Reader%3CBorrowed%3C\'bytes%3E%3E-for-Archive%3C\'bytes%3E"],[921,"impl-Reader%3C%26File%3E-for-Archive%3C\'static%3E"],[922,"impl-Reader%3C%26Path%3E-for-Archive%3C\'static%3E"],[923,"impl-Reader%3CCopied%3C\'bytes%3E%3E-for-Archive%3C\'static%3E"],[1028,"impl-Types"],[1029,"impl-Flags-for-Types"],[1030,"impl-Flags-for-Flags"],[1031,"impl-Flags"],[1171,"impl-PartialEq%3CHash%3E-for-FileHash"],[1172,"impl-PartialEq-for-FileHash"],[1173,"impl-PartialEq%3CHash%3E-for-DirectoryHash"],[1174,"impl-PartialEq-for-DirectoryHash"],[1175,"impl-PartialEq-for-Hash"],[1176,"impl-PartialEq%3CFileHash%3E-for-Hash"],[1177,"impl-PartialEq%3CDirectoryHash%3E-for-Hash"],[1188,"impl-Display-for-Error"],[1189,"impl-Debug-for-Error"],[1206,"impl-UpperHex-for-Types"],[1207,"impl-Octal-for-Types"],[1208,"impl-Binary-for-Types"],[1209,"impl-LowerHex-for-Types"],[1210,"impl-Debug-for-Types"],[1211,"impl-Debug-for-Flags"],[1212,"impl-Octal-for-Flags"],[1213,"impl-Binary-for-Flags"],[1214,"impl-LowerHex-for-Flags"],[1215,"impl-UpperHex-for-Flags"],[1217,"impl-From%3CError%3E-for-Error"],[1218,"impl-From%3CTryFromIntError%3E-for-Error"],[1219,"impl-From%3CError%3E-for-Error"],[1228,"impl-From%3CDirectoryHash%3E-for-Hash"],[1229,"impl-From%3CFileHash%3E-for-Hash"],[1232,"impl-From%3COptions%3E-for-ReadOptions"],[1233,"impl-From%3C%26Options%3E-for-ReadOptions"],[1234,"impl-From%3COptions%3E-for-ReadOptionsBuilder"],[1236,"impl-From%3C%26Options%3E-for-ReadOptionsBuilder"],[1237,"impl-From%3C%26Options%3E-for-CompressionOptions"],[1239,"impl-From%3COptions%3E-for-CompressionOptions"],[1240,"impl-From%3C%26Options%3E-for-CompressionOptionsBuilder"],[1241,"impl-From%3COptions%3E-for-CompressionOptionsBuilder"],[1245,"impl-From%3CT%3E-for-Key%3C\'static%3E"],[1246,"impl-From%3CFileHash%3E-for-Key%3C\'static%3E"],[1250,"impl-From%3CDirectoryHash%3E-for-Key%3C\'static%3E"],[1251,"impl-From%3CT%3E-for-Key%3C\'static%3E"],[1257,"impl-Flags-for-Types"],[1258,"impl-Types"],[1259,"impl-Flags-for-Flags"],[1260,"impl-Flags"],[1263,"impl-CompressableFrom%3C%26%5Bu8%5D%3E-for-File%3C\'bytes%3E"],[1264,"impl-CompressableFrom%3C%26%5Bu8;+N%5D%3E-for-File%3C\'bytes%3E"],[1265,"impl-CompressableFrom%3CBox%3C%5Bu8%5D%3E%3E-for-File%3C\'static%3E"],[1266,"impl-CompressableFrom%3C%26%5Bu8;+N%5D%3E-for-File%3C\'bytes%3E"],[1267,"impl-CompressableFrom%3C%26%5Bu8%5D%3E-for-File%3C\'bytes%3E"],[1268,"impl-CompressableFrom%3CBox%3C%5Bu8%5D%3E%3E-for-File%3C\'static%3E"],[1314,"impl-IntoIterator-for-%26Directory%3C\'bytes%3E"],[1315,"impl-IntoIterator-for-Directory%3C\'bytes%3E"],[1316,"impl-IntoIterator-for-%26mut+Directory%3C\'bytes%3E"],[1317,"impl-IntoIterator-for-%26Archive%3C\'bytes%3E"],[1318,"impl-IntoIterator-for-%26mut+Archive%3C\'bytes%3E"],[1319,"impl-IntoIterator-for-Archive%3C\'bytes%3E"],[1366,"impl-PartialOrd-for-FileHash"],[1367,"impl-PartialOrd%3CHash%3E-for-FileHash"],[1368,"impl-PartialOrd-for-DirectoryHash"],[1369,"impl-PartialOrd%3CHash%3E-for-DirectoryHash"],[1370,"impl-PartialOrd%3CDirectoryHash%3E-for-Hash"],[1371,"impl-PartialOrd%3CFileHash%3E-for-Hash"],[1372,"impl-PartialOrd-for-Hash"],[1375,"impl-ReaderWithOptions%3C%26Path%3E-for-File%3C\'static%3E"],[1376,"impl-ReaderWithOptions%3C%26File%3E-for-File%3C\'static%3E"],[1377,"impl-ReaderWithOptions%3CBorrowed%3C\'bytes%3E%3E-for-File%3C\'bytes%3E"],[1378,"impl-ReaderWithOptions%3CCopied%3C\'bytes%3E%3E-for-File%3C\'static%3E"],[1379,"impl-Reader%3C%26Path%3E-for-Archive%3C\'static%3E"],[1380,"impl-Reader%3CCopied%3C\'bytes%3E%3E-for-Archive%3C\'static%3E"],[1381,"impl-Reader%3CBorrowed%3C\'bytes%3E%3E-for-Archive%3C\'bytes%3E"],[1382,"impl-Reader%3C%26File%3E-for-Archive%3C\'static%3E"]],"a":{"fallout 3":[238],"fallout 4":[111],"fallout new vegas":[238],"fnv":[238],"fo3":[238],"morrowind":[237],"new vegas":[238],"oblivion":[238],"skyrim":[238],"special edition":[238],"sse":[238],"starfield":[111],"tes5":[238]}}\ +}'); +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/settings.html b/settings.html new file mode 100644 index 0000000..a75d480 --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/src-files.js b/src-files.js new file mode 100644 index 0000000..a6608a2 --- /dev/null +++ b/src-files.js @@ -0,0 +1,4 @@ +var srcIndex = JSON.parse('{\ +"ba2":["",[["fo4",[],["archive.rs","chunk.rs","file.rs","hashing.rs","mod.rs"]],["tes3",[],["archive.rs","file.rs","hashing.rs","mod.rs"]],["tes4",[],["archive.rs","directory.rs","file.rs","hashing.rs","mod.rs"]]],["cc.rs","containers.rs","derive.rs","guess.rs","hashing.rs","io.rs","lib.rs","protocols.rs"]]\ +}'); +createSrcSidebar(); diff --git a/src/ba2/cc.rs.html b/src/ba2/cc.rs.html new file mode 100644 index 0000000..344f28a --- /dev/null +++ b/src/ba2/cc.rs.html @@ -0,0 +1,43 @@ +cc.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+
#[must_use]
+pub(crate) const fn make_four(cc: &[u8]) -> u32 {
+    let buffer = match cc.len() {
+        0 => [0, 0, 0, 0],
+        1 => [cc[0], 0, 0, 0],
+        2 => [cc[0], cc[1], 0, 0],
+        3 => [cc[0], cc[1], cc[2], 0],
+        _ => [cc[0], cc[1], cc[2], cc[3]],
+    };
+    u32::from_le_bytes(buffer)
+}
+
+#[test]
+fn test() {
+    assert_eq!(make_four(b""), 0x00000000);
+    assert_eq!(make_four(b"A"), 0x00000041);
+    assert_eq!(make_four(b"AB"), 0x00004241);
+    assert_eq!(make_four(b"ABC"), 0x00434241);
+    assert_eq!(make_four(b"ABCD"), 0x44434241);
+    assert_eq!(make_four(b"ABCDE"), 0x44434241);
+}
+
\ No newline at end of file diff --git a/src/ba2/containers.rs.html b/src/ba2/containers.rs.html new file mode 100644 index 0000000..9867967 --- /dev/null +++ b/src/ba2/containers.rs.html @@ -0,0 +1,569 @@ +containers.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+
use core::ops::Range;
+use memmap2::Mmap;
+use std::sync::Arc;
+
+#[derive(Clone, Debug)]
+struct Mapping {
+    pos: usize,
+    len: usize,
+    mapping: Arc<Mmap>,
+}
+
+impl Mapping {
+    #[must_use]
+    pub(crate) fn as_bytes(&self) -> &[u8] {
+        &self.mapping[self.pos..self.pos + self.len]
+    }
+
+    #[must_use]
+    pub(crate) fn as_ptr(&self) -> *const u8 {
+        self.as_bytes().as_ptr()
+    }
+
+    #[must_use]
+    pub(crate) fn is_empty(&self) -> bool {
+        self.len == 0
+    }
+
+    #[must_use]
+    pub(crate) fn len(&self) -> usize {
+        self.len
+    }
+}
+
+#[derive(Clone, Debug)]
+enum BytesInner<'bytes> {
+    Owned(Box<[u8]>),
+    Borrowed(&'bytes [u8]),
+    Mapped(Mapping),
+}
+
+use BytesInner::*;
+
+impl From<Mapping> for BytesInner<'static> {
+    fn from(value: Mapping) -> Self {
+        Mapped(value)
+    }
+}
+
+#[derive(Clone, Debug)]
+pub(crate) struct Bytes<'bytes> {
+    inner: BytesInner<'bytes>,
+}
+
+impl<'bytes> Bytes<'bytes> {
+    #[must_use]
+    pub(crate) fn as_bytes(&self) -> &[u8] {
+        match &self.inner {
+            Owned(x) => x,
+            Borrowed(x) => x,
+            Mapped(x) => x.as_bytes(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn as_ptr(&self) -> *const u8 {
+        match &self.inner {
+            Owned(x) => x.as_ptr(),
+            Borrowed(x) => x.as_ptr(),
+            Mapped(x) => x.as_ptr(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn from_borrowed(bytes: &'bytes [u8]) -> Self {
+        Self {
+            inner: Borrowed(bytes),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn is_empty(&self) -> bool {
+        match &self.inner {
+            Owned(x) => x.is_empty(),
+            Borrowed(x) => x.is_empty(),
+            Mapped(x) => x.is_empty(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn len(&self) -> usize {
+        match &self.inner {
+            Owned(x) => x.len(),
+            Borrowed(x) => x.len(),
+            Mapped(x) => x.len(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn into_owned(self) -> Bytes<'static> {
+        Bytes {
+            inner: match self.inner {
+                Owned(x) => Owned(x),
+                Borrowed(x) => Owned(x.into()),
+                Mapped(x) => Mapped(x),
+            },
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn into_compressable(
+        self,
+        decompressed_len: Option<usize>,
+    ) -> CompressableBytes<'bytes> {
+        CompressableBytes {
+            inner: match (self.inner, decompressed_len) {
+                (Owned(x), Some(len)) => OwnedCompressed(x, len),
+                (Owned(x), None) => OwnedDecompressed(x),
+                (Borrowed(x), Some(len)) => BorrowedCompressed(x, len),
+                (Borrowed(x), None) => BorrowedDecompressed(x),
+                (Mapped(x), Some(len)) => MappedCompressed(x, len),
+                (Mapped(x), None) => MappedDecompressed(x),
+            },
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn copy_slice(&self, slice: Range<usize>) -> Self {
+        match &self.inner {
+            Owned(x) => Self {
+                inner: Owned(x[slice].into()),
+            },
+            Borrowed(x) => Self {
+                inner: Borrowed(&x[slice]),
+            },
+            Mapped(x) => Self {
+                inner: Mapping {
+                    pos: x.pos + slice.start,
+                    len: slice.len(),
+                    mapping: x.mapping.clone(),
+                }
+                .into(),
+            },
+        }
+    }
+}
+
+impl Bytes<'static> {
+    #[must_use]
+    pub(crate) fn from_owned(bytes: Box<[u8]>) -> Self {
+        Self {
+            inner: Owned(bytes),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn from_mapped(pos: usize, len: usize, mapping: Arc<Mmap>) -> Self {
+        Self {
+            inner: Mapping { pos, len, mapping }.into(),
+        }
+    }
+}
+
+impl<'bytes> Default for Bytes<'bytes> {
+    fn default() -> Self {
+        Self {
+            inner: Owned(Box::default()),
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+enum CompressableBytesInner<'bytes> {
+    OwnedDecompressed(Box<[u8]>),
+    OwnedCompressed(Box<[u8]>, usize),
+    BorrowedDecompressed(&'bytes [u8]),
+    BorrowedCompressed(&'bytes [u8], usize),
+    MappedDecompressed(Mapping),
+    MappedCompressed(Mapping, usize),
+}
+
+use CompressableBytesInner::*;
+
+#[derive(Clone, Debug)]
+pub(crate) struct CompressableBytes<'bytes> {
+    inner: CompressableBytesInner<'bytes>,
+}
+
+impl<'bytes> CompressableBytes<'bytes> {
+    #[must_use]
+    pub(crate) fn as_bytes(&self) -> &[u8] {
+        match &self.inner {
+            OwnedDecompressed(x) | OwnedCompressed(x, _) => x,
+            BorrowedDecompressed(x) | BorrowedCompressed(x, _) => x,
+            MappedDecompressed(x) | MappedCompressed(x, _) => x.as_bytes(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn as_ptr(&self) -> *const u8 {
+        match &self.inner {
+            OwnedDecompressed(x) | OwnedCompressed(x, _) => x.as_ptr(),
+            BorrowedDecompressed(x) | BorrowedCompressed(x, _) => x.as_ptr(),
+            MappedDecompressed(x) | MappedCompressed(x, _) => x.as_ptr(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn from_borrowed(bytes: &'bytes [u8], decompressed_len: Option<usize>) -> Self {
+        Self {
+            inner: match decompressed_len {
+                Some(len) => BorrowedCompressed(bytes, len),
+                None => BorrowedDecompressed(bytes),
+            },
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn is_empty(&self) -> bool {
+        match &self.inner {
+            OwnedDecompressed(x) | OwnedCompressed(x, _) => x.is_empty(),
+            BorrowedDecompressed(x) | BorrowedCompressed(x, _) => x.is_empty(),
+            MappedDecompressed(x) | MappedCompressed(x, _) => x.is_empty(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn len(&self) -> usize {
+        match &self.inner {
+            OwnedDecompressed(x) | OwnedCompressed(x, _) => x.len(),
+            BorrowedDecompressed(x) | BorrowedCompressed(x, _) => x.len(),
+            MappedDecompressed(x) | MappedCompressed(x, _) => x.len(),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn into_owned(self) -> CompressableBytes<'static> {
+        CompressableBytes {
+            inner: match self.inner {
+                OwnedDecompressed(x) => OwnedDecompressed(x),
+                OwnedCompressed(x, y) => OwnedCompressed(x, y),
+                BorrowedDecompressed(x) => OwnedDecompressed(x.into()),
+                BorrowedCompressed(x, y) => OwnedCompressed(x.into(), y),
+                MappedDecompressed(x) => MappedDecompressed(x),
+                MappedCompressed(x, y) => MappedCompressed(x, y),
+            },
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn decompressed_len(&self) -> Option<usize> {
+        match &self.inner {
+            OwnedDecompressed(_) | BorrowedDecompressed(_) | MappedDecompressed(_) => None,
+            OwnedCompressed(_, x) | BorrowedCompressed(_, x) | MappedCompressed(_, x) => Some(*x),
+        }
+    }
+
+    #[must_use]
+    pub(crate) fn is_compressed(&self) -> bool {
+        match &self.inner {
+            OwnedDecompressed(_) | BorrowedDecompressed(_) | MappedDecompressed(_) => false,
+            OwnedCompressed(_, _) | BorrowedCompressed(_, _) | MappedCompressed(_, _) => true,
+        }
+    }
+}
+
+impl CompressableBytes<'static> {
+    #[must_use]
+    pub(crate) fn from_owned(bytes: Box<[u8]>, decompressed_len: Option<usize>) -> Self {
+        Self {
+            inner: match decompressed_len {
+                Some(len) => OwnedCompressed(bytes, len),
+                None => OwnedDecompressed(bytes),
+            },
+        }
+    }
+}
+
+impl<'bytes> Default for CompressableBytes<'bytes> {
+    fn default() -> Self {
+        Self {
+            inner: OwnedDecompressed(Box::default()),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/derive.rs.html b/src/ba2/derive.rs.html new file mode 100644 index 0000000..3674956 --- /dev/null +++ b/src/ba2/derive.rs.html @@ -0,0 +1,1179 @@ +derive.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+
macro_rules! reader {
+    ($this:ident => $result:ident) => {
+        impl<'bytes> crate::Reader<crate::Borrowed<'bytes>> for $this<'bytes> {
+            type Error = Error;
+            type Item = $result<$this<'bytes>>;
+
+            fn read(source: crate::Borrowed<'bytes>) -> Result<Self::Item> {
+                let mut source = crate::io::BorrowedSource::from(source.0);
+                Self::do_read(&mut source)
+            }
+        }
+
+        impl<'bytes> crate::Reader<crate::Copied<'bytes>> for $this<'static> {
+            type Error = Error;
+            type Item = $result<$this<'static>>;
+
+            fn read(source: crate::Copied<'bytes>) -> Result<Self::Item> {
+                let mut source = crate::io::CopiedSource::from(source.0);
+                Self::do_read(&mut source)
+            }
+        }
+
+        impl crate::Reader<&::std::fs::File> for $this<'static> {
+            type Error = Error;
+            type Item = $result<$this<'static>>;
+
+            fn read(source: &::std::fs::File) -> Result<Self::Item> {
+                let mut source = crate::io::MappedSource::try_from(source)?;
+                Self::do_read(&mut source)
+            }
+        }
+
+        impl crate::Reader<&::std::path::Path> for $this<'static> {
+            type Error = Error;
+            type Item = $result<$this<'static>>;
+
+            fn read(source: &::std::path::Path) -> Result<Self::Item> {
+                let fd = ::std::fs::File::open(source)?;
+                Self::read(&fd)
+            }
+        }
+    };
+}
+
+pub(crate) use reader;
+
+macro_rules! reader_with_options {
+    (($this:ident: $options:ident) => $result:ident) => {
+        impl<'bytes> crate::ReaderWithOptions<crate::Borrowed<'bytes>> for $this<'bytes> {
+            type Error = Error;
+            type Item = $result<$this<'bytes>>;
+            type Options = $options;
+
+            fn read(
+                source: crate::Borrowed<'bytes>,
+                options: &Self::Options,
+            ) -> Result<Self::Item> {
+                let mut source = crate::io::BorrowedSource::from(source.0);
+                Self::do_read(&mut source, options)
+            }
+        }
+
+        impl<'bytes> crate::ReaderWithOptions<crate::Copied<'bytes>> for $this<'static> {
+            type Error = Error;
+            type Item = $result<$this<'static>>;
+            type Options = $options;
+
+            fn read(source: crate::Copied<'bytes>, options: &Self::Options) -> Result<Self::Item> {
+                let mut source = crate::io::CopiedSource::from(source.0);
+                Self::do_read(&mut source, options)
+            }
+        }
+
+        impl crate::ReaderWithOptions<&::std::fs::File> for $this<'static> {
+            type Error = Error;
+            type Item = $result<$this<'static>>;
+            type Options = $options;
+
+            fn read(source: &::std::fs::File, options: &Self::Options) -> Result<Self::Item> {
+                let mut source = crate::io::MappedSource::try_from(source)?;
+                Self::do_read(&mut source, options)
+            }
+        }
+
+        impl crate::ReaderWithOptions<&::std::path::Path> for $this<'static> {
+            type Error = Error;
+            type Item = $result<$this<'static>>;
+            type Options = $options;
+
+            fn read(source: &::std::path::Path, options: &Self::Options) -> Result<Self::Item> {
+                let fd = ::std::fs::File::open(source)?;
+                Self::read(&fd, options)
+            }
+        }
+    };
+}
+
+pub(crate) use reader_with_options;
+
+macro_rules! bytes {
+    ($this:ident) => {
+        impl<'bytes> crate::Sealed for $this<'bytes> {}
+
+        impl<'bytes> $this<'bytes> {
+            #[must_use]
+            pub fn as_bytes(&self) -> &[u8] {
+                self.bytes.as_bytes()
+            }
+
+            #[must_use]
+            pub fn as_ptr(&self) -> *const u8 {
+                self.bytes.as_ptr()
+            }
+
+            #[must_use]
+            pub fn into_owned(self) -> $this<'static> {
+                #[allow(clippy::needless_update)]
+                $this {
+                    bytes: self.bytes.into_owned(),
+                    ..self
+                }
+            }
+
+            #[must_use]
+            pub fn is_empty(&self) -> bool {
+                self.bytes.is_empty()
+            }
+
+            #[must_use]
+            pub fn len(&self) -> usize {
+                self.bytes.len()
+            }
+
+            #[must_use]
+            pub fn new() -> Self {
+                Self::default()
+            }
+        }
+    };
+}
+
+pub(crate) use bytes;
+
+macro_rules! compressable_bytes {
+    ($this:ident: $options:ident) => {
+        crate::derive::bytes!($this);
+
+        impl<'bytes> $this<'bytes> {
+            pub fn compress(&self, options: &$options) -> Result<$this<'static>> {
+                let mut bytes = ::std::vec::Vec::new();
+                self.compress_into(&mut bytes, options)?;
+                Ok(self.copy_with(CompressableBytes::from_owned(
+                    bytes.into(),
+                    Some(self.len()),
+                )))
+            }
+
+            pub fn decompress(&self, options: &$options) -> Result<$this<'static>> {
+                let mut bytes = ::std::vec::Vec::new();
+                self.decompress_into(&mut bytes, options)?;
+                Ok(self.copy_with(CompressableBytes::from_owned(bytes.into(), None)))
+            }
+
+            #[must_use]
+            pub fn decompressed_len(&self) -> ::core::option::Option<usize> {
+                self.bytes.decompressed_len()
+            }
+
+            #[must_use]
+            pub fn is_compressed(&self) -> bool {
+                self.bytes.is_compressed()
+            }
+
+            #[must_use]
+            pub fn is_decompressed(&self) -> bool {
+                !self.is_compressed()
+            }
+
+            pub fn write<Out>(&self, stream: &mut Out, options: &$options) -> Result<()>
+            where
+                Out: ?::core::marker::Sized + ::std::io::Write,
+            {
+                if self.is_compressed() {
+                    let mut bytes = ::std::vec::Vec::new();
+                    self.decompress_into(&mut bytes, options)?;
+                    stream.write_all(&bytes)?;
+                } else {
+                    stream.write_all(self.as_bytes())?;
+                }
+
+                Ok(())
+            }
+        }
+
+        #[allow(clippy::needless_update)]
+        impl<'bytes, const N: usize> crate::CompressableFrom<&'bytes [u8; N]> for $this<'bytes> {
+            fn from_compressed(value: &'bytes [u8; N], decompressed_len: usize) -> Self {
+                Self::from_compressed(value.as_slice(), decompressed_len)
+            }
+
+            fn from_decompressed(value: &'bytes [u8; N]) -> Self {
+                Self::from_decompressed(value.as_slice())
+            }
+        }
+
+        #[allow(clippy::needless_update)]
+        impl<'bytes> crate::CompressableFrom<&'bytes [u8]> for $this<'bytes> {
+            fn from_compressed(value: &'bytes [u8], decompressed_len: usize) -> Self {
+                Self {
+                    bytes: CompressableBytes::from_borrowed(value, Some(decompressed_len)),
+                    ..Default::default()
+                }
+            }
+
+            fn from_decompressed(value: &'bytes [u8]) -> Self {
+                Self {
+                    bytes: CompressableBytes::from_borrowed(value, None),
+                    ..Default::default()
+                }
+            }
+        }
+
+        #[allow(clippy::needless_update)]
+        impl crate::CompressableFrom<::std::boxed::Box<[u8]>> for $this<'static> {
+            fn from_compressed(value: ::std::boxed::Box<[u8]>, decompressed_len: usize) -> Self {
+                Self {
+                    bytes: CompressableBytes::from_owned(value, Some(decompressed_len)),
+                    ..Default::default()
+                }
+            }
+
+            fn from_decompressed(value: ::std::boxed::Box<[u8]>) -> Self {
+                Self {
+                    bytes: CompressableBytes::from_owned(value, None),
+                    ..Default::default()
+                }
+            }
+        }
+    };
+}
+
+pub(crate) use compressable_bytes;
+
+macro_rules! key {
+    ($this:ident: $hash:ident) => {
+        /// A key for indexing into the relevant mapping.
+        #[derive(::core::clone::Clone, ::core::fmt::Debug, ::core::default::Default)]
+        pub struct $this<'bytes> {
+            pub(crate) hash: $hash,
+            pub(crate) name: crate::containers::Bytes<'bytes>,
+        }
+
+        impl<'bytes> $this<'bytes> {
+            #[must_use]
+            pub fn hash(&self) -> &$hash {
+                &self.hash
+            }
+
+            #[must_use]
+            pub fn name(&self) -> &::bstr::BStr {
+                ::bstr::BStr::new(self.name.as_bytes())
+            }
+        }
+
+        // false positive
+        #[allow(clippy::unconditional_recursion)]
+        impl<'bytes> ::core::cmp::PartialEq for $this<'bytes> {
+            fn eq(&self, other: &Self) -> bool {
+                self.hash.eq(&other.hash)
+            }
+        }
+
+        impl<'bytes> ::core::cmp::Eq for $this<'bytes> {}
+
+        impl<'bytes> ::core::cmp::PartialOrd for $this<'bytes> {
+            fn partial_cmp(&self, other: &Self) -> ::core::option::Option<::core::cmp::Ordering> {
+                Some(self.cmp(other))
+            }
+        }
+
+        impl<'bytes> ::core::cmp::Ord for $this<'bytes> {
+            fn cmp(&self, other: &Self) -> ::core::cmp::Ordering {
+                self.hash.cmp(&other.hash)
+            }
+        }
+
+        impl<'bytes> ::core::borrow::Borrow<$hash> for $this<'bytes> {
+            fn borrow(&self) -> &$hash {
+                &self.hash
+            }
+        }
+
+        impl ::core::convert::From<$hash> for $this<'static> {
+            fn from(value: $hash) -> Self {
+                Self {
+                    hash: value,
+                    name: crate::containers::Bytes::default(),
+                }
+            }
+        }
+
+        impl<T> ::core::convert::From<T> for $this<'static>
+        where
+            T: ::core::convert::Into<::bstr::BString>,
+        {
+            fn from(value: T) -> Self {
+                let mut name = value.into();
+                let hash = Self::hash_in_place(&mut name);
+                let v: Vec<u8> = name.into();
+                Self {
+                    hash,
+                    name: crate::containers::Bytes::from_owned(v.into()),
+                }
+            }
+        }
+    };
+}
+
+pub(crate) use key;
+
+macro_rules! mapping {
+    (
+        $(#[doc=$doc:literal])*
+        $this:ident
+        $mapping:ident: ($key:ident: $hash:ident) => $value:ident
+    ) => {
+        pub(crate) type $mapping<'bytes> =
+            ::std::collections::BTreeMap<$key<'bytes>, $value<'bytes>>;
+
+        impl<'bytes> crate::Sealed for $this<'bytes> {}
+
+        $(#[doc=$doc])*
+        #[derive(::core::clone::Clone, ::core::fmt::Debug, ::core::default::Default)]
+        pub struct $this<'bytes> {
+            pub(crate) map: $mapping<'bytes>,
+        }
+
+        impl<'bytes> $this<'bytes> {
+            pub fn clear(&mut self) {
+                self.map.clear();
+            }
+
+            #[must_use]
+            pub fn get<K>(&self, key: &K) -> ::core::option::Option<&$value<'bytes>>
+            where
+                K: ::core::borrow::Borrow<$hash>,
+            {
+                self.map.get(key.borrow())
+            }
+
+            #[must_use]
+            pub fn get_key_value<K>(
+                &self,
+                key: &K,
+            ) -> ::core::option::Option<(&$key<'bytes>, &$value<'bytes>)>
+            where
+                K: ::core::borrow::Borrow<$hash>,
+            {
+                self.map.get_key_value(key.borrow())
+            }
+
+            #[must_use]
+            pub fn get_mut<K>(&mut self, key: &K) -> ::core::option::Option<&mut $value<'bytes>>
+            where
+                K: ::core::borrow::Borrow<$hash>,
+            {
+                self.map.get_mut(key.borrow())
+            }
+
+            pub fn insert<K>(
+                &mut self,
+                key: K,
+                value: $value<'bytes>,
+            ) -> ::core::option::Option<$value<'bytes>>
+            where
+                K: ::core::convert::Into<$key<'bytes>>,
+            {
+                self.map.insert(key.into(), value)
+            }
+
+            #[must_use]
+            pub fn is_empty(&self) -> bool {
+                self.map.is_empty()
+            }
+
+            pub fn iter(
+                &self,
+            ) -> impl ::core::iter::Iterator<Item = (&$key<'bytes>, &$value<'bytes>)> {
+                self.map.iter()
+            }
+
+            pub fn iter_mut(
+                &mut self,
+            ) -> impl ::core::iter::Iterator<Item = (&$key<'bytes>, &mut $value<'bytes>)> {
+                self.map.iter_mut()
+            }
+
+            pub fn keys(&self) -> impl ::core::iter::Iterator<Item = &$key<'bytes>> {
+                self.map.keys()
+            }
+
+            #[must_use]
+            pub fn len(&self) -> usize {
+                self.map.len()
+            }
+
+            #[must_use]
+            pub fn new() -> Self {
+                Self::default()
+            }
+
+            pub fn remove<K>(&mut self, key: &K) -> ::core::option::Option<$value<'bytes>>
+            where
+                K: ::core::borrow::Borrow<$hash>,
+            {
+                self.map.remove(key.borrow())
+            }
+
+            pub fn remove_entry<K>(
+                &mut self,
+                key: &K,
+            ) -> ::core::option::Option<($key<'bytes>, $value<'bytes>)>
+            where
+                K: ::core::borrow::Borrow<$hash>,
+            {
+                self.map.remove_entry(key.borrow())
+            }
+
+            pub fn values(&self) -> impl ::core::iter::Iterator<Item = &$value<'bytes>> {
+                self.map.values()
+            }
+
+            pub fn values_mut(
+                &mut self,
+            ) -> impl ::core::iter::Iterator<Item = &mut $value<'bytes>> {
+                self.map.values_mut()
+            }
+        }
+
+        impl<'bytes> ::core::iter::FromIterator<($key<'bytes>, $value<'bytes>)> for $this<'bytes> {
+            fn from_iter<T>(iter: T) -> Self
+            where
+                T: ::core::iter::IntoIterator<Item = ($key<'bytes>, $value<'bytes>)>,
+            {
+                Self {
+                    map: iter.into_iter().collect(),
+                }
+            }
+        }
+
+        impl<'bytes> ::core::iter::IntoIterator for $this<'bytes> {
+            type Item = <$mapping<'bytes> as ::core::iter::IntoIterator>::Item;
+            type IntoIter = <$mapping<'bytes> as ::core::iter::IntoIterator>::IntoIter;
+
+            fn into_iter(self) -> Self::IntoIter {
+                self.map.into_iter()
+            }
+        }
+
+        impl<'bytes, 'this> ::core::iter::IntoIterator for &'this $this<'bytes> {
+            type Item = <&'this $mapping<'bytes> as ::core::iter::IntoIterator>::Item;
+            type IntoIter = <&'this $mapping<'bytes> as ::core::iter::IntoIterator>::IntoIter;
+
+            fn into_iter(self) -> Self::IntoIter {
+                self.map.iter()
+            }
+        }
+
+        impl<'bytes, 'this> ::core::iter::IntoIterator for &'this mut $this<'bytes> {
+            type Item = <&'this mut $mapping<'bytes> as ::core::iter::IntoIterator>::Item;
+            type IntoIter = <&'this mut $mapping<'bytes> as ::core::iter::IntoIterator>::IntoIter;
+
+            fn into_iter(self) -> Self::IntoIter {
+                self.map.iter_mut()
+            }
+        }
+    };
+}
+
+pub(crate) use mapping;
+
+macro_rules! archive {
+    (
+        $(#[doc=$doc:literal])*
+        $this:ident => $result:ident
+        $mapping:ident: ($key:ident: $hash:ident) => $value:ident
+    ) => {
+        crate::derive::mapping! {
+            $(#[doc=$doc])*
+            $this
+            $mapping: ($key: $hash) => $value
+        }
+        crate::derive::reader!($this => $result);
+    };
+}
+
+pub(crate) use archive;
+
+macro_rules! hash {
+    ($this:ident) => {
+        /// See also [`struct@Hash`].
+        #[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
+        #[repr(transparent)]
+        pub struct $this(Hash);
+
+        impl $this {
+            #[must_use]
+            pub fn new() -> Self {
+                Self::default()
+            }
+        }
+
+        impl ::core::convert::AsMut<Hash> for $this {
+            fn as_mut(&mut self) -> &mut Hash {
+                &mut self.0
+            }
+        }
+
+        impl ::core::convert::AsRef<Hash> for $this {
+            fn as_ref(&self) -> &Hash {
+                &self.0
+            }
+        }
+
+        impl ::core::borrow::Borrow<Hash> for $this {
+            fn borrow(&self) -> &Hash {
+                &self.0
+            }
+        }
+
+        impl ::core::borrow::BorrowMut<Hash> for $this {
+            fn borrow_mut(&mut self) -> &mut Hash {
+                &mut self.0
+            }
+        }
+
+        impl ::core::ops::Deref for $this {
+            type Target = Hash;
+
+            fn deref(&self) -> &Self::Target {
+                &self.0
+            }
+        }
+
+        impl ::core::ops::DerefMut for $this {
+            fn deref_mut(&mut self) -> &mut Self::Target {
+                &mut self.0
+            }
+        }
+
+        impl ::core::convert::From<Hash> for $this {
+            fn from(value: Hash) -> Self {
+                Self(value)
+            }
+        }
+
+        impl ::core::convert::From<$this> for Hash {
+            fn from(value: $this) -> Self {
+                value.0
+            }
+        }
+
+        impl ::core::cmp::PartialEq<Hash> for $this {
+            fn eq(&self, other: &Hash) -> bool {
+                self.0.eq(other)
+            }
+        }
+
+        impl ::core::cmp::PartialEq<$this> for Hash {
+            fn eq(&self, other: &$this) -> bool {
+                self.eq(&other.0)
+            }
+        }
+
+        impl ::core::cmp::PartialOrd<Hash> for $this {
+            fn partial_cmp(&self, other: &Hash) -> ::core::option::Option<::core::cmp::Ordering> {
+                self.0.partial_cmp(other)
+            }
+        }
+
+        impl ::core::cmp::PartialOrd<$this> for Hash {
+            fn partial_cmp(&self, other: &$this) -> ::core::option::Option<::core::cmp::Ordering> {
+                self.partial_cmp(&other.0)
+            }
+        }
+    };
+}
+
+pub(crate) use hash;
+
\ No newline at end of file diff --git a/src/ba2/fo4/archive.rs.html b/src/ba2/fo4/archive.rs.html new file mode 100644 index 0000000..acbbb9b --- /dev/null +++ b/src/ba2/fo4/archive.rs.html @@ -0,0 +1,2469 @@ +archive.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+
use crate::{
+    containers::Bytes,
+    derive,
+    fo4::{
+        self, Chunk, CompressionFormat, DX10Header, Error, File, FileHash, FileHeader, Format,
+        GNMFHeader, Hash, Result, Version,
+    },
+    io::{Endian, Sink, Source},
+    protocols::WString,
+};
+use bstr::BString;
+use std::io::Write;
+
+mod constants {
+    use crate::cc;
+
+    pub(crate) const MAGIC: u32 = cc::make_four(b"BTDX");
+
+    pub(crate) const GNRL: u32 = cc::make_four(b"GNRL");
+    pub(crate) const DX10: u32 = cc::make_four(b"DX10");
+    pub(crate) const GNMF: u32 = cc::make_four(b"GNMF");
+
+    pub(crate) const HEADER_SIZE_V1: usize = 0x18;
+    pub(crate) const HEADER_SIZE_V2: usize = 0x20;
+    pub(crate) const HEADER_SIZE_V3: usize = 0x24;
+
+    pub(crate) const FILE_HEADER_SIZE_GNRL: u16 = 0x10;
+    pub(crate) const FILE_HEADER_SIZE_DX10: u16 = 0x18;
+    pub(crate) const FILE_HEADER_SIZE_GNMF: u16 = 0x30;
+
+    pub(crate) const CHUNK_SIZE_GNRL: usize = 0x14;
+    pub(crate) const CHUNK_SIZE_DX10: usize = 0x18;
+    pub(crate) const CHUNK_SIZE_GNMF: usize = 0x18;
+
+    pub(crate) const CHUNK_SENTINEL: u32 = 0xBAAD_F00D;
+}
+
+struct Offsets {
+    file_data: usize,
+    strings: usize,
+}
+
+impl Offsets {
+    #[must_use]
+    pub fn new(archive: &Archive, options: Options) -> Self {
+        let chunks_offset = match options.version {
+            Version::v1 => constants::HEADER_SIZE_V1,
+            Version::v2 => constants::HEADER_SIZE_V2,
+            Version::v3 => constants::HEADER_SIZE_V3,
+        };
+
+        let file_data_offset = {
+            let (file_header_size, chunk_size) = match options.format {
+                Format::GNRL => (constants::FILE_HEADER_SIZE_GNRL, constants::CHUNK_SIZE_GNRL),
+                Format::DX10 => (constants::FILE_HEADER_SIZE_DX10, constants::CHUNK_SIZE_DX10),
+                Format::GNMF => (constants::FILE_HEADER_SIZE_GNMF, constants::CHUNK_SIZE_GNMF),
+            };
+            let chunks_count: usize = archive.values().map(File::len).sum();
+            chunks_offset
+                + (archive.len() * usize::from(file_header_size))
+                + (chunks_count * chunk_size)
+        };
+
+        let strings_offset = {
+            let data_size: usize = archive.values().flat_map(File::iter).map(Chunk::len).sum();
+            file_data_offset + data_size
+        };
+
+        Self {
+            file_data: file_data_offset,
+            strings: strings_offset,
+        }
+    }
+}
+
+struct Header {
+    version: Version,
+    format: Format,
+    file_count: u32,
+    string_table_offset: u64,
+    compression_format: CompressionFormat,
+}
+
+/// See also [`ArchiveOptions`](Options).
+#[derive(Clone, Copy, Debug, Default)]
+#[repr(transparent)]
+pub struct OptionsBuilder(Options);
+
+impl OptionsBuilder {
+    #[must_use]
+    pub fn build(self) -> Options {
+        self.0
+    }
+
+    #[must_use]
+    pub fn compression_format(mut self, compression_format: CompressionFormat) -> Self {
+        self.0.compression_format = compression_format;
+        self
+    }
+
+    #[must_use]
+    pub fn format(mut self, format: Format) -> Self {
+        self.0.format = format;
+        self
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    #[must_use]
+    pub fn strings(mut self, strings: bool) -> Self {
+        self.0.strings = strings;
+        self
+    }
+
+    #[must_use]
+    pub fn version(mut self, version: Version) -> Self {
+        self.0.version = version;
+        self
+    }
+}
+
+/// Info about the contents of the given archive.
+///
+/// ```rust
+/// use ba2::fo4::{ArchiveOptions, CompressionFormat, Format, Version};
+///
+/// // Write an archive for FO4/FO76, GNRL format
+/// let _ = ArchiveOptions::builder()
+///     .format(Format::GNRL)
+///     .version(Version::v1)
+///     .compression_format(CompressionFormat::Zip)
+///     .build();
+///
+/// // Write an archive for FO4/FO76, DX10 format
+/// let _ = ArchiveOptions::builder()
+///     .format(Format::DX10)
+///     .version(Version::v1)
+///     .compression_format(CompressionFormat::Zip)
+///     .build();
+///
+/// // Write an archive for SF, GNRL format
+/// let _ = ArchiveOptions::builder()
+///     .format(Format::GNRL)
+///     .version(Version::v2)
+///     .compression_format(CompressionFormat::Zip)
+///     .build();
+///
+/// // Write an archive for SF, DX10 format
+/// let _ = ArchiveOptions::builder()
+///     .format(Format::DX10)
+///     .version(Version::v3)
+///     .compression_format(CompressionFormat::LZ4)
+///     .build();
+/// ```
+#[derive(Clone, Copy, Debug, Default)]
+pub struct Options {
+    format: Format,
+    version: Version,
+    compression_format: CompressionFormat,
+    strings: bool,
+}
+
+impl Options {
+    #[must_use]
+    pub fn builder() -> OptionsBuilder {
+        OptionsBuilder::new()
+    }
+
+    #[must_use]
+    pub fn compression_format(&self) -> CompressionFormat {
+        self.compression_format
+    }
+
+    #[must_use]
+    pub fn format(&self) -> Format {
+        self.format
+    }
+
+    #[must_use]
+    pub fn strings(&self) -> bool {
+        self.strings
+    }
+
+    #[must_use]
+    pub fn version(&self) -> Version {
+        self.version
+    }
+}
+
+derive::key!(Key: FileHash);
+
+impl<'bytes> Key<'bytes> {
+    #[must_use]
+    fn hash_in_place(name: &mut BString) -> FileHash {
+        fo4::hash_file_in_place(name)
+    }
+}
+
+type ReadResult<T> = (T, Options);
+derive::archive! {
+    /// Represents the FO4 revision of the ba2 format.
+    Archive => ReadResult
+    Map: (Key: FileHash) => File
+}
+
+impl<'bytes> Archive<'bytes> {
+    pub fn write<Out>(&self, stream: &mut Out, options: &Options) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let mut sink = Sink::new(stream);
+        let (header, mut offsets) = self.make_header(*options)?;
+        Self::write_header(&mut sink, &header)?;
+
+        for (key, file) in self {
+            Self::write_file(&mut sink, &header, &mut offsets, key.hash(), file)?;
+        }
+
+        for file in self.values() {
+            for chunk in file {
+                sink.write_bytes(chunk.as_bytes())?;
+            }
+        }
+
+        if options.strings {
+            for key in self.keys() {
+                sink.write_protocol::<WString>(key.name(), Endian::Little)?;
+            }
+        }
+
+        Ok(())
+    }
+
+    fn make_header(&self, options: Options) -> Result<(Header, Offsets)> {
+        let offsets = Offsets::new(self, options);
+        Ok((
+            Header {
+                version: options.version,
+                format: options.format,
+                file_count: self.len().try_into()?,
+                string_table_offset: if options.strings {
+                    offsets.strings as u64
+                } else {
+                    0
+                },
+                compression_format: options.compression_format,
+            },
+            offsets,
+        ))
+    }
+
+    fn write_chunk<Out>(
+        sink: &mut Sink<Out>,
+        header: &Header,
+        offsets: &mut Offsets,
+        chunk: &Chunk<'bytes>,
+    ) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let data_offset: u64 = offsets.file_data.try_into()?;
+        offsets.file_data += chunk.len();
+        let (compressed_size, decompressed_size): (u32, u32) =
+            if let Some(decompressed_len) = chunk.decompressed_len() {
+                (chunk.len().try_into()?, decompressed_len.try_into()?)
+            } else {
+                (0, chunk.len().try_into()?)
+            };
+        sink.write(
+            &(data_offset, compressed_size, decompressed_size),
+            Endian::Little,
+        )?;
+
+        match (header.format, &chunk.mips) {
+            (Format::GNRL, None) => (),
+            (Format::DX10 | Format::GNMF, Some(mips)) => {
+                sink.write(&(*mips.start(), *mips.end()), Endian::Little)?;
+            }
+            _ => {
+                return Err(Error::FormatMismatch);
+            }
+        }
+
+        sink.write(&constants::CHUNK_SENTINEL, Endian::Little)?;
+        Ok(())
+    }
+
+    fn write_file<Out>(
+        sink: &mut Sink<Out>,
+        header: &Header,
+        offsets: &mut Offsets,
+        hash: &FileHash,
+        file: &File<'bytes>,
+    ) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        Self::write_hash(sink, hash)?;
+
+        let chunk_count: u8 = file.len().try_into()?;
+        let chunk_size = match header.format {
+            Format::GNRL => constants::FILE_HEADER_SIZE_GNRL,
+            Format::DX10 => constants::FILE_HEADER_SIZE_DX10,
+            Format::GNMF => constants::FILE_HEADER_SIZE_GNMF,
+        };
+        sink.write(&(0u8, chunk_count, chunk_size), Endian::Little)?;
+
+        match (header.format, &file.header) {
+            (Format::GNRL, FileHeader::GNRL) => (),
+            (Format::DX10, FileHeader::DX10(x)) => {
+                sink.write(
+                    &(
+                        x.height,
+                        x.width,
+                        x.mip_count,
+                        x.format,
+                        x.flags,
+                        x.tile_mode,
+                    ),
+                    Endian::Little,
+                )?;
+            }
+            (Format::GNMF, FileHeader::GNMF(x)) => {
+                sink.write(&x.metadata, Endian::Little)?;
+            }
+            (_, _) => {
+                return Err(Error::FormatMismatch);
+            }
+        }
+
+        for chunk in file {
+            Self::write_chunk(sink, header, offsets, chunk)?;
+        }
+
+        Ok(())
+    }
+
+    fn write_hash<Out>(sink: &mut Sink<Out>, hash: &Hash) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        sink.write(&(hash.file, hash.extension, hash.directory), Endian::Little)?;
+        Ok(())
+    }
+
+    fn write_header<Out>(sink: &mut Sink<Out>, header: &Header) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let format = match header.format {
+            Format::GNRL => constants::GNRL,
+            Format::DX10 => constants::DX10,
+            Format::GNMF => constants::GNMF,
+        };
+
+        sink.write(
+            &(
+                constants::MAGIC,
+                header.version as u32,
+                format,
+                header.file_count,
+                header.string_table_offset,
+            ),
+            Endian::Little,
+        )?;
+
+        if header.version >= Version::v2 {
+            sink.write(&1u64, Endian::Little)?;
+        }
+
+        if header.version >= Version::v3 {
+            let format: u32 = match header.compression_format {
+                CompressionFormat::Zip => 0,
+                CompressionFormat::LZ4 => 3,
+            };
+            sink.write(&format, Endian::Little)?;
+        }
+
+        Ok(())
+    }
+
+    fn do_read<In>(source: &mut In) -> Result<ReadResult<Self>>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let header = Self::read_header(source)?;
+        let mut map = Map::default();
+        let mut strings: usize = header.string_table_offset.try_into()?;
+        for _ in 0..header.file_count {
+            let (key, value) = Self::read_file(source, &header, &mut strings)?;
+            map.insert(key, value);
+        }
+
+        Ok((
+            Self { map },
+            Options {
+                format: header.format,
+                version: header.version,
+                compression_format: header.compression_format,
+                strings: header.string_table_offset != 0,
+            },
+        ))
+    }
+
+    fn read_chunk<In>(source: &mut In, header: &Header) -> Result<Chunk<'bytes>>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let (data_offset, compressed_size, decompressed_size): (u64, u32, u32) =
+            source.read(Endian::Little)?;
+        let mips = match header.format {
+            Format::GNRL => None,
+            Format::DX10 | Format::GNMF => {
+                let (mip_first, mip_last) = source.read(Endian::Little)?;
+                Some(mip_first..=mip_last)
+            }
+        };
+
+        let sentinel = source.read(Endian::Little)?;
+        if sentinel != constants::CHUNK_SENTINEL {
+            return Err(Error::InvalidChunkSentinel(sentinel));
+        }
+
+        let bytes = source.save_restore_position(|source| -> Result<Bytes<'bytes>> {
+            source.seek_absolute(data_offset.try_into()?)?;
+            let len = if compressed_size == 0 {
+                decompressed_size
+            } else {
+                compressed_size
+            };
+            let bytes = source.read_bytes(len as usize)?;
+            Ok(bytes)
+        })??;
+        let decompressed_len = (compressed_size != 0).then_some(decompressed_size as usize);
+        let bytes = bytes.into_compressable(decompressed_len);
+
+        Ok(Chunk { bytes, mips })
+    }
+
+    fn read_file<In>(
+        source: &mut In,
+        header: &Header,
+        strings: &mut usize,
+    ) -> Result<(Key<'bytes>, File<'bytes>)>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let name = if *strings == 0 {
+            Bytes::default()
+        } else {
+            source.save_restore_position(|source| -> Result<Bytes<'bytes>> {
+                source.seek_absolute(*strings)?;
+                let name = source.read_protocol::<WString>(Endian::Little)?;
+                *strings = source.stream_position();
+                Ok(name)
+            })??
+        };
+
+        let hash = Self::read_hash(source)?;
+        let (_, chunk_count, chunk_size): (u8, u8, u16) = source.read(Endian::Little)?;
+        if !matches!(
+            (header.format, chunk_size),
+            (Format::GNRL, constants::FILE_HEADER_SIZE_GNRL)
+                | (Format::DX10, constants::FILE_HEADER_SIZE_DX10)
+                | (Format::GNMF, constants::FILE_HEADER_SIZE_GNMF)
+        ) {
+            return Err(Error::InvalidChunkSize(chunk_size));
+        }
+
+        let file_header = match header.format {
+            Format::GNRL => FileHeader::GNRL,
+            Format::DX10 => {
+                let (height, width, mip_count, format, flags, tile_mode) =
+                    source.read(Endian::Little)?;
+                DX10Header {
+                    height,
+                    width,
+                    mip_count,
+                    format,
+                    flags,
+                    tile_mode,
+                }
+                .into()
+            }
+            Format::GNMF => {
+                let metadata = source.read(Endian::Little)?;
+                GNMFHeader { metadata }.into()
+            }
+        };
+
+        let mut chunks = Vec::with_capacity(chunk_count.into());
+        for _ in 0..chunk_count {
+            let chunk = Self::read_chunk(source, header)?;
+            chunks.push(chunk);
+        }
+
+        Ok((
+            Key {
+                hash: hash.into(),
+                name,
+            },
+            File {
+                chunks,
+                header: file_header,
+            },
+        ))
+    }
+
+    fn read_hash<In>(source: &mut In) -> Result<Hash>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let (file, extension, directory) = source.read(Endian::Little)?;
+        Ok(Hash {
+            file,
+            extension,
+            directory,
+        })
+    }
+
+    fn read_header<In>(source: &mut In) -> Result<Header>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let (magic, version, contents_format, file_count, string_table_offset) =
+            source.read(Endian::Little)?;
+
+        if magic != constants::MAGIC {
+            return Err(Error::InvalidMagic(magic));
+        }
+
+        let format = match contents_format {
+            constants::GNRL => Format::GNRL,
+            constants::DX10 => Format::DX10,
+            constants::GNMF => Format::GNMF,
+            _ => return Err(Error::InvalidFormat(contents_format)),
+        };
+
+        let version = match version {
+            1 => Version::v1,
+            2 => Version::v2,
+            3 => Version::v3,
+            _ => return Err(Error::InvalidVersion(version)),
+        };
+
+        if version >= Version::v2 {
+            source.read::<u64>(Endian::Little)?;
+        }
+
+        let compression_format = if version >= Version::v3 {
+            let format: u32 = source.read(Endian::Little)?;
+            if format == 3 {
+                CompressionFormat::LZ4
+            } else {
+                CompressionFormat::Zip
+            }
+        } else {
+            CompressionFormat::Zip
+        };
+
+        Ok(Header {
+            version,
+            format,
+            file_count,
+            string_table_offset,
+            compression_format,
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        cc,
+        fo4::{
+            Archive, ArchiveKey, ArchiveOptions, CompressionFormat, Error, File, FileHeader,
+            FileReadOptions, Format, Version,
+        },
+        prelude::*,
+        Borrowed, CompressionResult,
+    };
+    use anyhow::Context as _;
+    use bstr::ByteSlice as _;
+    use core::mem;
+    use directxtex::DXGI_FORMAT;
+    use memmap2::Mmap;
+    use std::{
+        ffi::OsString,
+        fs,
+        io::{self, Read as _},
+        path::{Path, PathBuf},
+        str::FromStr as _,
+    };
+    use walkdir::WalkDir;
+
+    #[test]
+    fn default_state() {
+        let archive = Archive::default();
+        assert!(archive.is_empty());
+        assert_eq!(archive.len(), 0);
+    }
+
+    #[test]
+    fn chunking_strategy() -> anyhow::Result<()> {
+        let file = {
+            let options = FileReadOptions::builder()
+                .format(Format::DX10)
+                .compression_result(CompressionResult::Compressed)
+                .build();
+            File::read(Path::new("data/fo4_chunk_test/test.dds"), &options)
+                .context("failed to read file")?
+        };
+
+        let FileHeader::DX10(header) = &file.header else {
+            anyhow::bail!("file was not dx10");
+        };
+        assert_eq!(header.mip_count, 11);
+        assert_eq!(
+            header.format,
+            DXGI_FORMAT::DXGI_FORMAT_BC1_UNORM.bits() as u8
+        );
+        assert_eq!(file.len(), 3);
+
+        let mut index = 0;
+        let mut next_chunk = || {
+            let chunk = &file[index];
+            index += 1;
+            let Some(mips) = &chunk.mips else {
+                anyhow::bail!("chunk was missing mips");
+            };
+            Ok((chunk, mips))
+        };
+
+        let (chunk, mips) = next_chunk()?;
+        assert_eq!(chunk.decompressed_len(), Some(0x8_0000));
+        assert_eq!(*mips, 0..=0);
+
+        let (chunk, mips) = next_chunk()?;
+        assert_eq!(chunk.decompressed_len(), Some(0x2_0000));
+        assert_eq!(*mips, 1..=1);
+
+        let (chunk, mips) = next_chunk()?;
+        assert_eq!(chunk.decompressed_len(), Some(0xAAB8));
+        assert_eq!(*mips, 2..=10);
+
+        Ok(())
+    }
+
+    #[test]
+    fn archives_with_compression() -> anyhow::Result<()> {
+        let root_path = Path::new("data/fo4_compression_test");
+        for archive_name in ["normal.ba2", "xbox.ba2"] {
+            let (archive, options) = Archive::read(root_path.join(archive_name).as_path())
+                .context("failed to read archive")?;
+            assert_eq!(options.format(), Format::GNRL);
+            assert_eq!(options.compression_format(), CompressionFormat::Zip);
+
+            let root_path = root_path.join("data");
+            for file_path in WalkDir::new(&root_path) {
+                if let Ok(file_path) = file_path {
+                    let metadata = file_path.metadata().with_context(|| {
+                        format!(
+                            "failed to get metadata for file path: {:?}",
+                            file_path.path()
+                        )
+                    })?;
+                    if metadata.is_file() {
+                        let key = file_path
+                            .path()
+                            .strip_prefix(&root_path)
+                            .with_context(|| {
+                                format!(
+                                "failed to strip prefix ({root_path:?}) from path ({file_path:?})"
+                            )
+                            })?
+                            .as_os_str();
+                        let file = archive
+                            .get(&ArchiveKey::from(key.as_encoded_bytes()))
+                            .with_context(|| format!("failed to get file with key: {key:?}"))?;
+                        assert_eq!(file.len(), 1);
+
+                        let chunk = &file[0];
+                        assert!(chunk.is_compressed());
+                        let chunk = chunk.decompress(&Default::default()).with_context(|| {
+                            format!("failed to decompress chunk for file: {file_path:?}")
+                        })?;
+                        assert!(chunk.is_decompressed());
+                        assert_eq!(chunk.len() as u64, metadata.len());
+
+                        let mut original_data = Vec::new();
+                        fs::File::open(file_path.path())
+                            .with_context(|| format!("failed to open file: {file_path:?}"))?
+                            .read_to_end(&mut original_data)
+                            .with_context(|| format!("failed to read from file: {file_path:?}"))?;
+                        assert_eq!(chunk.len(), original_data.len());
+                        assert_eq!(chunk.as_bytes(), &original_data);
+                    }
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    #[test]
+    fn files_with_cubemaps() -> anyhow::Result<()> {
+        let file = {
+            let options = FileReadOptions::builder()
+                .format(Format::DX10)
+                .compression_result(CompressionResult::Compressed)
+                .build();
+            File::read(Path::new("data/fo4_cubemap_test/blacksky_e.dds"), &options)
+                .context("failed to read file")?
+        };
+
+        let FileHeader::DX10(header) = &file.header else {
+            anyhow::bail!("file was not dx10");
+        };
+        assert_eq!(header.mip_count, 10);
+        assert_eq!(header.flags, 1);
+        assert_eq!(header.tile_mode, 8);
+        assert_eq!(file.len(), 1);
+
+        let chunk = &file[0];
+        let Some(mips) = &chunk.mips else {
+            anyhow::bail!("chunk was missing mips");
+        };
+
+        assert_eq!(*mips, 0..=9);
+        assert_eq!(chunk.decompressed_len(), Some(0x20_00A0));
+
+        Ok(())
+    }
+
+    #[test]
+    fn read_write_texture_archives() -> anyhow::Result<()> {
+        let path = Path::new("data/fo4_dds_test/in.ba2");
+        let original = {
+            let fd =
+                fs::File::open(path).with_context(|| format!("failed to open file: {path:?}"))?;
+            unsafe { Mmap::map(&fd) }
+                .with_context(|| format!("failed to memory map file: {path:?}"))?
+        };
+
+        let (archive, options) = Archive::read(Borrowed(&original[..]))
+            .with_context(|| format!("failed to read archive: {path:?}"))?;
+        assert_eq!(options.compression_format, CompressionFormat::Zip);
+        assert_eq!(options.format, Format::DX10);
+        assert_eq!(options.strings, true);
+        assert_eq!(options.version, Version::v1);
+        assert_eq!(archive.len(), 1);
+
+        let file = archive
+            .get(&ArchiveKey::from("Fence006_1K_Roughness.dds"))
+            .context("failed to get file from archive")?;
+        let FileHeader::DX10(header) = &file.header else {
+            anyhow::bail!("file header was not dx10");
+        };
+        assert_eq!(file.len(), 3);
+        assert_eq!(header.height, 1024);
+        assert_eq!(header.width, 1024);
+        assert_eq!(header.mip_count, 11);
+        assert_eq!(header.format, 98);
+        assert_eq!(header.flags, 0);
+        assert_eq!(header.tile_mode, 8);
+
+        let mut idx = 0;
+        let mut next_chunk = || {
+            let chunk = &file[idx];
+            idx += 1;
+            let Some(mips) = &chunk.mips else {
+                anyhow::bail!("chunk extra was missing mips");
+            };
+            Ok((chunk, mips))
+        };
+
+        let (chunk, mips) = next_chunk()?;
+        assert_eq!(chunk.len(), 0x100_000);
+        assert_eq!(*mips.start(), 0);
+        assert_eq!(*mips.end(), 0);
+
+        let (chunk, mips) = next_chunk()?;
+        assert_eq!(chunk.len(), 0x40_000);
+        assert_eq!(*mips.start(), 1);
+        assert_eq!(*mips.end(), 1);
+
+        let (chunk, mips) = next_chunk()?;
+        assert_eq!(chunk.len(), 0x15_570);
+        assert_eq!(*mips.start(), 2);
+        assert_eq!(*mips.end(), 10);
+
+        let copy = {
+            let mut v = Vec::new();
+            archive
+                .write(&mut v, &options)
+                .with_context(|| format!("failed to write archive: {path:?}"))?;
+            v
+        };
+
+        assert_eq!(original.len(), copy.len());
+        assert_eq!(&original[..], copy);
+        Ok(())
+    }
+
+    #[allow(non_camel_case_types, non_snake_case)]
+    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+    struct DDS_PIXELFORMAT {
+        dwSize: u32,
+        dwFlags: u32,
+        dwFourCC: u32,
+        dwRGBBitCount: u32,
+        dwRBitMask: u32,
+        dwGBitMask: u32,
+        dwBBitMask: u32,
+        dwABitMask: u32,
+    }
+
+    #[allow(non_camel_case_types, non_snake_case)]
+    #[derive(Clone, Copy, Debug)]
+    struct DDS_HEADER {
+        dwSize: u32,
+        dwFlags: u32,
+        dwHeight: u32,
+        dwWidth: u32,
+        dwPitchOrLinearSize: u32,
+        dwDepth: u32,
+        dwMipMapCount: u32,
+        #[allow(unused)]
+        dwReserved1: [u32; 11],
+        ddspf: DDS_PIXELFORMAT,
+        dwCaps: u32,
+        dwCaps2: u32,
+        dwCaps3: u32,
+        dwCaps4: u32,
+        #[allow(unused)]
+        dwReserved2: u32,
+    }
+
+    impl Eq for DDS_HEADER {}
+
+    impl PartialEq for DDS_HEADER {
+        fn eq(&self, other: &Self) -> bool {
+            macro_rules! compare {
+                ($name:ident) => {
+                    self.$name == other.$name
+                };
+            }
+
+            compare!(dwSize)
+                && compare!(dwFlags)
+                && compare!(dwHeight)
+                && compare!(dwWidth)
+                && compare!(dwPitchOrLinearSize)
+                && compare!(dwDepth)
+                && compare!(dwMipMapCount)
+                && compare!(ddspf)
+                && compare!(dwCaps)
+                && compare!(dwCaps2)
+                && compare!(dwCaps3)
+                && compare!(dwCaps4)
+        }
+    }
+
+    #[allow(non_camel_case_types, non_snake_case)]
+    #[derive(Clone, Copy, Debug)]
+    struct DDS_HEADER_DXT10 {
+        dxgiFormat: DXGI_FORMAT,
+        resourceDimension: u32,
+        miscFlag: u32,
+        arraySize: u32,
+        #[allow(unused)]
+        miscFlags2: u32,
+    }
+
+    impl Eq for DDS_HEADER_DXT10 {}
+
+    impl PartialEq for DDS_HEADER_DXT10 {
+        fn eq(&self, other: &Self) -> bool {
+            macro_rules! compare {
+                ($name:ident) => {
+                    self.$name == other.$name
+                };
+            }
+
+            compare!(dxgiFormat)
+                && compare!(resourceDimension)
+                && compare!(miscFlag)
+                && compare!(arraySize)
+        }
+    }
+
+    #[allow(non_snake_case)]
+    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+    struct DDS9Header {
+        dwMagic: u32,
+        header: DDS_HEADER,
+    }
+
+    #[allow(non_snake_case)]
+    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+    struct DDS10Header {
+        header9: DDS9Header,
+        header10: DDS_HEADER_DXT10,
+    }
+
+    #[test]
+    fn pack_unpack_texture_archives() -> anyhow::Result<()> {
+        let root = Path::new("data/fo4_dds_test");
+        let original = {
+            let fd = fs::File::open(root.join("in.ba2")).context("failed to open archive")?;
+            unsafe { Mmap::map(&fd) }.context("failed to map archive")?
+        };
+
+        let (archive, options) =
+            Archive::read(Borrowed(&original[..])).context("failed to read archive")?;
+        assert_eq!(options.format(), Format::DX10);
+        assert_eq!(options.compression_format(), CompressionFormat::Zip);
+
+        {
+            let file_name = "Fence006_1K_Roughness.dds";
+            let original = {
+                let fd = fs::File::open(root.join(file_name)).context("failed to open file")?;
+                unsafe { Mmap::map(&fd) }.context("failed to map file")?
+            };
+            let file = {
+                let from_archive = archive
+                    .get(&ArchiveKey::from(file_name))
+                    .context("failed to get file from archive")?;
+                assert!(!from_archive.is_empty());
+                for chunk in from_archive {
+                    assert!(chunk.is_decompressed());
+                }
+
+                let options = FileReadOptions::builder().format(Format::DX10).build();
+                let from_disk =
+                    File::read(Borrowed(&original), &options).context("failed to read file")?;
+                assert_eq!(from_disk.header, from_archive.header);
+                assert_eq!(from_disk.len(), from_archive.len());
+                for (disk, archived) in from_disk.iter().zip(from_archive) {
+                    assert_eq!(disk.mips, archived.mips);
+                    assert_eq!(disk.as_bytes(), archived.as_bytes());
+                }
+
+                from_archive
+            };
+            let copy = {
+                let mut v = Vec::new();
+                file.write(&mut v, &Default::default())
+                    .context("failed to write file")?;
+                v
+            };
+            assert_eq!(original.len(), copy.len());
+
+            let header_size = mem::size_of::<DDS10Header>();
+            let get_header = |bytes: &[u8]| unsafe {
+                bytes[..header_size]
+                    .as_ptr()
+                    .cast::<DDS10Header>()
+                    .read_unaligned()
+            };
+            let original_header = get_header(&original[..]);
+            let copy_header = get_header(&copy);
+            assert_eq!(original_header, copy_header);
+            assert_eq!(&original[header_size..], &copy[header_size..]);
+        }
+
+        let copy = {
+            let mut v = Vec::new();
+            archive
+                .write(&mut v, &options)
+                .context("failed to write archive")?;
+            v
+        };
+
+        assert_eq!(original.len(), copy.len());
+        assert_eq!(&original[..], &copy);
+
+        Ok(())
+    }
+
+    #[test]
+    fn dx9() -> anyhow::Result<()> {
+        let root = Path::new("data/fo4_dx9_test");
+        let file_names = ["dx9.dds", "blacksky_e.dds", "bleakfallscube_e.dds"];
+        for file_name in file_names {
+            let original = {
+                let fd = fs::File::open(root.join(file_name))
+                    .with_context(|| format!("failed to open file: {file_name}"))?;
+                unsafe { Mmap::map(&fd) }
+                    .with_context(|| format!("failed to map file: {file_name}"))?
+            };
+
+            let copy = {
+                let options = FileReadOptions::builder().format(Format::DX10).build();
+                let file = File::read(Borrowed(&original[..]), &options)
+                    .with_context(|| format!("failed to read file: {file_name}"))?;
+                let mut v = Vec::new();
+                file.write(&mut v, &Default::default())
+                    .with_context(|| format!("failed to write file: {file_name}"))?;
+                v
+            };
+
+            assert_eq!(original.len(), copy.len());
+            assert_eq!(&original[..], &copy);
+        }
+
+        Ok(())
+    }
+
+    #[test]
+    fn invalid_exhausted() -> anyhow::Result<()> {
+        let path = Path::new("data/fo4_invalid_test/invalid_exhausted.ba2");
+        match Archive::read(path) {
+            Err(Error::Io(error)) => {
+                assert_eq!(error.kind(), io::ErrorKind::UnexpectedEof);
+                Ok(())
+            }
+            Err(err) => Err(err.into()),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_format() -> anyhow::Result<()> {
+        let path = Path::new("data/fo4_invalid_test/invalid_format.ba2");
+        match Archive::read(path) {
+            Err(Error::InvalidFormat(x)) if x == cc::make_four(b"BLAH") => Ok(()),
+            Err(err) => Err(anyhow::Error::from(err)),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_magic() -> anyhow::Result<()> {
+        let path = Path::new("data/fo4_invalid_test/invalid_magic.ba2");
+        match Archive::read(path) {
+            Err(Error::InvalidMagic(x)) if x == cc::make_four(b"BLAH") => Ok(()),
+            Err(err) => Err(anyhow::Error::from(err)),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_sentinel() -> anyhow::Result<()> {
+        let path = Path::new("data/fo4_invalid_test/invalid_sentinel.ba2");
+        match Archive::read(path) {
+            Err(Error::InvalidChunkSentinel(0xDEADBEEF)) => Ok(()),
+            Err(err) => Err(anyhow::Error::from(err)),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_size() -> anyhow::Result<()> {
+        let path = Path::new("data/fo4_invalid_test/invalid_size.ba2");
+        match Archive::read(path) {
+            Err(Error::InvalidChunkSize(0xCCCC)) => Ok(()),
+            Err(err) => Err(anyhow::Error::from(err)),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_version() -> anyhow::Result<()> {
+        let path = Path::new("data/fo4_invalid_test/invalid_version.ba2");
+        match Archive::read(path) {
+            Err(Error::InvalidVersion(0x101)) => Ok(()),
+            Err(err) => Err(anyhow::Error::from(err)),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn string_tables_are_optional() -> anyhow::Result<()> {
+        let root = Path::new("data/fo4_missing_string_table_test");
+        let original = {
+            let fd = fs::File::open(root.join("in.ba2")).context("failed to open archive")?;
+            unsafe { Mmap::map(&fd) }.context("failed to map archive")?
+        };
+
+        let (archive, options) = {
+            let (archive, options) =
+                Archive::read(Borrowed(&original[..])).context("failed to read archive")?;
+            assert_eq!(options.format(), Format::GNRL);
+
+            let file_name = "misc/example.txt";
+            let (key, file) = archive
+                .get_key_value(&ArchiveKey::from("misc/example.txt"))
+                .context("failed to get file")?;
+            assert!(key.name().is_empty());
+            assert_eq!(file.len(), 1);
+
+            let chunk = &file[0];
+            let mapped = {
+                let fd = fs::File::open(root.join("data").join(file_name))
+                    .context("failed to open original file")?;
+                unsafe { Mmap::map(&fd) }.context("failed to map file")?
+            };
+
+            assert!(chunk.is_decompressed());
+            assert_eq!(chunk.len(), mapped.len());
+            assert_eq!(chunk.as_bytes(), &mapped[..]);
+
+            (archive, options)
+        };
+
+        let copy = {
+            let mut v = Vec::new();
+            archive
+                .write(&mut v, &options)
+                .context("failed to write archive")?;
+            v
+        };
+
+        assert_eq!(copy.len(), original.len());
+        assert_eq!(copy, &original[..]);
+
+        Ok(())
+    }
+
+    #[test]
+    fn write_general_archives() -> anyhow::Result<()> {
+        let root = Path::new("data/fo4_write_test/data");
+
+        struct Info {
+            key: ArchiveKey<'static>,
+            path: OsString,
+        }
+
+        impl Info {
+            #[must_use]
+            fn new(file: u32, extension: &[u8], directory: u32, path: &str) -> Self {
+                let key: ArchiveKey = path.into();
+                assert_eq!(key.hash().file, file);
+                assert_eq!(key.hash().extension, cc::make_four(extension));
+                assert_eq!(key.hash().directory, directory);
+                Self {
+                    key,
+                    path: OsString::from_str(path).unwrap(),
+                }
+            }
+        }
+
+        let infos = [
+            Info::new(
+                0x35B94567,
+                b"png",
+                0x5FE2DC26,
+                "Background/background_tilemap.png",
+            ),
+            Info::new(
+                0x53D5F897,
+                b"png",
+                0xD9A32978,
+                "Characters/character_0003.png",
+            ),
+            Info::new(0x36F72750, b"txt", 0x60648919, "Construct 3/Readme.txt"),
+            Info::new(0xCA042B67, b"txt", 0x29246A47, "Share/License.txt"),
+            Info::new(0xDA3773A6, b"png", 0x0B0A447E, "Tilemap/tiles.png"),
+            Info::new(0x785183FF, b"png", 0xDA3773A6, "Tiles/tile_0003.png"),
+        ];
+
+        let mappings: Vec<_> = infos
+            .iter()
+            .map(|info| {
+                let path: PathBuf = [root.as_os_str(), info.path.as_ref()].into_iter().collect();
+                let fd = fs::File::open(&path)
+                    .with_context(|| format!("failed to open file: {path:?}"))?;
+                let map = unsafe { Mmap::map(&fd) }
+                    .with_context(|| format!("failed to memory map file: {path:?}"))?;
+                Ok(map)
+            })
+            .collect::<anyhow::Result<_>>()?;
+        let main: Archive = infos
+            .iter()
+            .zip(&mappings)
+            .map(|(info, mapping)| {
+                let file = File::read(Borrowed(&mapping[..]), &Default::default())?;
+                Ok((info.key.clone(), file))
+            })
+            .collect::<anyhow::Result<_>>()?;
+
+        let test = |strings: bool| -> anyhow::Result<()> {
+            let buffer = {
+                let mut v = Vec::new();
+                let options = ArchiveOptions::builder().strings(strings).build();
+                main.write(&mut v, &options)
+                    .context("failed to write archive to buffer")?;
+                v
+            };
+
+            let (child, options) =
+                Archive::read(Borrowed(&buffer)).context("failed to read archive from buffer")?;
+            assert_eq!(options.strings(), strings);
+            assert_eq!(main.len(), child.len());
+
+            for (info, mapping) in infos.iter().zip(&mappings) {
+                let file = child.get_key_value(&info.key).with_context(|| {
+                    format!("failed to get file: {}", info.key.name().to_str_lossy())
+                })?;
+                assert_eq!(file.0.hash(), info.key.hash());
+                assert_eq!(file.1.len(), 1);
+                if strings {
+                    assert_eq!(file.0.name(), info.key.name());
+                }
+
+                let chunk = &file.1[0];
+                let decompressed_chunk = if chunk.is_compressed() {
+                    let result = chunk.decompress(&Default::default()).with_context(|| {
+                        format!(
+                            "failed to decompress chunk: {}",
+                            info.key.name().to_str_lossy()
+                        )
+                    })?;
+                    Some(result)
+                } else {
+                    None
+                };
+                let decompressed_bytes = decompressed_chunk.as_ref().unwrap_or(chunk).as_bytes();
+                assert_eq!(decompressed_bytes, &mapping[..]);
+            }
+
+            Ok(())
+        };
+
+        test(true)?;
+        test(false)?;
+
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/fo4/chunk.rs.html b/src/ba2/fo4/chunk.rs.html new file mode 100644 index 0000000..b81749a --- /dev/null +++ b/src/ba2/fo4/chunk.rs.html @@ -0,0 +1,447 @@ +chunk.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+
use crate::{
+    containers::CompressableBytes,
+    derive,
+    fo4::{ArchiveOptions, CompressionFormat, CompressionLevel, Error, Result},
+};
+use core::ops::RangeInclusive;
+use flate2::{
+    write::{ZlibDecoder, ZlibEncoder},
+    Compress, Compression,
+};
+use lzzzz::{lz4, lz4_hc};
+use std::io::Write;
+
+/// See also [`ChunkCompressionOptions`](CompressionOptions).
+#[derive(Debug, Default)]
+#[repr(transparent)]
+pub struct CompressionOptionsBuilder(CompressionOptions);
+
+impl CompressionOptionsBuilder {
+    #[must_use]
+    pub fn build(self) -> CompressionOptions {
+        self.0
+    }
+
+    #[must_use]
+    pub fn compression_format(mut self, compression_format: CompressionFormat) -> Self {
+        self.0.compression_format = compression_format;
+        self
+    }
+
+    #[must_use]
+    pub fn compression_level(mut self, compression_level: CompressionLevel) -> Self {
+        self.0.compression_level = compression_level;
+        self
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+}
+
+impl From<ArchiveOptions> for CompressionOptionsBuilder {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for CompressionOptionsBuilder {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self(value.into())
+    }
+}
+
+/// Common parameters to configure how chunks are compressed.
+///
+/// ```rust
+/// use ba2::fo4::{ChunkCompressionOptions, CompressionFormat, CompressionLevel};
+///
+/// // Configure for FO4/FO76
+/// let _ = ChunkCompressionOptions::builder()
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::FO4)
+///     .build();
+///
+/// // Configure for FO4 on the xbox
+/// let _ = ChunkCompressionOptions::builder()
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::FO4Xbox)
+///     .build();
+///
+/// // Configure for SF, GNRL format
+/// let _ = ChunkCompressionOptions::builder()
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::SF)
+///     .build();
+///
+/// // Configure for SF, DX10 format
+/// let _ = ChunkCompressionOptions::builder()
+///     .compression_format(CompressionFormat::LZ4)
+///     .build();
+/// ```
+#[derive(Clone, Copy, Debug, Default)]
+pub struct CompressionOptions {
+    pub(crate) compression_format: CompressionFormat,
+    pub(crate) compression_level: CompressionLevel,
+}
+
+impl CompressionOptions {
+    #[must_use]
+    pub fn builder() -> CompressionOptionsBuilder {
+        CompressionOptionsBuilder::new()
+    }
+
+    #[must_use]
+    pub fn compression_format(&self) -> CompressionFormat {
+        self.compression_format
+    }
+
+    #[must_use]
+    pub fn compression_level(&self) -> CompressionLevel {
+        self.compression_level
+    }
+}
+
+impl From<ArchiveOptions> for CompressionOptions {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for CompressionOptions {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self {
+            compression_format: value.compression_format(),
+            ..Default::default()
+        }
+    }
+}
+
+/// Represents a chunk of a file within the FO4 virtual filesystem.
+#[derive(Clone, Debug, Default)]
+pub struct Chunk<'bytes> {
+    pub(crate) bytes: CompressableBytes<'bytes>,
+    pub mips: Option<RangeInclusive<u16>>,
+}
+
+derive::compressable_bytes!(Chunk: CompressionOptions);
+
+impl<'bytes> Chunk<'bytes> {
+    pub fn compress_into(&self, out: &mut Vec<u8>, options: &CompressionOptions) -> Result<()> {
+        if self.is_compressed() {
+            Err(Error::AlreadyCompressed)
+        } else {
+            match options.compression_format {
+                CompressionFormat::Zip => match options.compression_level {
+                    CompressionLevel::FO4 => {
+                        self.compress_into_zlib(out, Compression::default(), 15)
+                    }
+                    CompressionLevel::FO4Xbox => {
+                        self.compress_into_zlib(out, Compression::best(), 12)
+                    }
+                    CompressionLevel::SF => self.compress_into_zlib(out, Compression::best(), 15),
+                },
+                CompressionFormat::LZ4 => self.compress_into_lz4(out),
+            }
+        }
+    }
+
+    pub fn decompress_into(&self, out: &mut Vec<u8>, options: &CompressionOptions) -> Result<()> {
+        let Some(decompressed_len) = self.decompressed_len() else {
+            return Err(Error::AlreadyDecompressed);
+        };
+
+        out.reserve_exact(decompressed_len);
+        let out_len = match options.compression_format {
+            CompressionFormat::Zip => self.decompress_into_zlib(out),
+            CompressionFormat::LZ4 => self.decompress_into_lz4(out),
+        }?;
+
+        if out_len == decompressed_len {
+            Ok(())
+        } else {
+            Err(Error::DecompressionSizeMismatch {
+                expected: decompressed_len,
+                actual: out_len,
+            })
+        }
+    }
+
+    pub(crate) fn copy_with<'other>(&self, bytes: CompressableBytes<'other>) -> Chunk<'other> {
+        Chunk {
+            bytes,
+            mips: self.mips.clone(),
+        }
+    }
+
+    fn compress_into_lz4(&self, out: &mut Vec<u8>) -> Result<()> {
+        lz4_hc::compress_to_vec(self.as_bytes(), out, lz4_hc::CLEVEL_MAX)?;
+        Ok(())
+    }
+
+    fn compress_into_zlib(
+        &self,
+        out: &mut Vec<u8>,
+        level: Compression,
+        window_bits: u8,
+    ) -> Result<()> {
+        let mut e = ZlibEncoder::new_with_compress(
+            out,
+            Compress::new_with_window_bits(level, true, window_bits),
+        );
+        e.write_all(self.as_bytes())?;
+        e.finish()?;
+        Ok(())
+    }
+
+    fn decompress_into_lz4(&self, out: &mut [u8]) -> Result<usize> {
+        let len = lz4::decompress(self.as_bytes(), out)?;
+        Ok(len)
+    }
+
+    fn decompress_into_zlib(&self, out: &mut Vec<u8>) -> Result<usize> {
+        let mut d = ZlibDecoder::new(out);
+        d.write_all(self.as_bytes())?;
+        Ok(d.total_out().try_into()?)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::Chunk;
+
+    #[test]
+    fn default_state() {
+        let c = Chunk::default();
+        assert!(c.is_empty());
+        assert!(!c.is_compressed());
+        assert!(c.is_decompressed());
+        assert_eq!(c.len(), 0);
+        assert_eq!(c.mips, None);
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/fo4/file.rs.html b/src/ba2/fo4/file.rs.html new file mode 100644 index 0000000..b1997bf --- /dev/null +++ b/src/ba2/fo4/file.rs.html @@ -0,0 +1,1761 @@ +file.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+
use crate::{
+    cc,
+    containers::CompressableBytes,
+    derive,
+    fo4::{
+        ArchiveOptions, Chunk, ChunkCompressionOptions, CompressionFormat, CompressionLevel, Error,
+        Format, Result,
+    },
+    io::{Endian, Sink, Source},
+    CompressionResult, Sealed,
+};
+use core::{
+    fmt::{self, Debug, Display, Formatter},
+    num::NonZeroUsize,
+    ops::{Index, IndexMut, Range, RangeBounds},
+    ptr::NonNull,
+    result, slice,
+};
+use directxtex::{ScratchImage, TexMetadata, CP_FLAGS, DDS_FLAGS, TEX_DIMENSION, TEX_MISC_FLAG};
+use std::{error, io::Write};
+
+/// File is at chunk capacity.
+pub struct CapacityError<'bytes>(Chunk<'bytes>);
+
+impl<'bytes> CapacityError<'bytes> {
+    #[must_use]
+    pub fn into_element(self) -> Chunk<'bytes> {
+        self.0
+    }
+}
+
+impl<'bytes> Debug for CapacityError<'bytes> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        <Self as Display>::fmt(self, f)
+    }
+}
+
+impl<'bytes> Display for CapacityError<'bytes> {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        write!(
+            f,
+            "could not insert another chunk because the file was already full"
+        )
+    }
+}
+
+impl<'bytes> error::Error for CapacityError<'bytes> {}
+
+/// See also [`FileReadOptions`](ReadOptions).
+#[derive(Debug, Default)]
+#[repr(transparent)]
+pub struct ReadOptionsBuilder(ReadOptions);
+
+impl ReadOptionsBuilder {
+    #[must_use]
+    pub fn build(self) -> ReadOptions {
+        self.0
+    }
+
+    #[must_use]
+    pub fn compression_format(mut self, compression_format: CompressionFormat) -> Self {
+        self.0.compression_options.compression_format = compression_format;
+        self
+    }
+
+    #[must_use]
+    pub fn compression_level(mut self, compression_level: CompressionLevel) -> Self {
+        self.0.compression_options.compression_level = compression_level;
+        self
+    }
+
+    #[must_use]
+    pub fn compression_result(mut self, compression_result: CompressionResult) -> Self {
+        self.0.compression_result = compression_result;
+        self
+    }
+
+    #[must_use]
+    pub fn format(mut self, format: Format) -> Self {
+        self.0.format = format;
+        self
+    }
+
+    #[must_use]
+    pub fn mip_chunk_height(mut self, mip_chunk_height: usize) -> Self {
+        self.0.mip_chunk_height = mip_chunk_height;
+        self
+    }
+
+    #[must_use]
+    pub fn mip_chunk_width(mut self, mip_chunk_width: usize) -> Self {
+        self.0.mip_chunk_width = mip_chunk_width;
+        self
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+}
+
+impl From<ArchiveOptions> for ReadOptionsBuilder {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for ReadOptionsBuilder {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self(value.into())
+    }
+}
+
+/// Common parameters to configure how files are read.
+///
+/// ```rust
+/// use ba2::{
+///     fo4::{CompressionFormat, CompressionLevel, FileReadOptions, Format},
+///     CompressionResult,
+/// };
+///
+/// // Read and compress a file for FO4/FO76, GNRL format
+/// let _ = FileReadOptions::builder()
+///     .format(Format::GNRL)
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::FO4)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+///
+/// // Read and compress a file for FO4/FO76, DX10 format
+/// let _ = FileReadOptions::builder()
+///     .format(Format::DX10)
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::FO4)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+///
+/// // Read and compress a file for FO4 on the xbox, GNRL format
+/// let _ = FileReadOptions::builder()
+///     .format(Format::GNRL)
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::FO4Xbox)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+///
+/// // Read and compress a file for FO4 on the xbox, DX10 format
+/// let _ = FileReadOptions::builder()
+///     .format(Format::DX10)
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::FO4Xbox)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+///
+/// // Read and compress a file for SF, GNRL format
+/// let _ = FileReadOptions::builder()
+///     .format(Format::GNRL)
+///     .compression_format(CompressionFormat::Zip)
+///     .compression_level(CompressionLevel::SF)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+///
+/// // Read and compress a file for SF, DX10 format
+/// let _ = FileReadOptions::builder()
+///     .format(Format::DX10)
+///     .compression_format(CompressionFormat::LZ4)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+/// ```
+#[derive(Clone, Copy, Debug)]
+pub struct ReadOptions {
+    format: Format,
+    mip_chunk_width: usize,
+    mip_chunk_height: usize,
+    compression_options: ChunkCompressionOptions,
+    compression_result: CompressionResult,
+}
+
+impl ReadOptions {
+    #[must_use]
+    pub fn builder() -> ReadOptionsBuilder {
+        ReadOptionsBuilder::new()
+    }
+
+    #[must_use]
+    pub fn compression_format(&self) -> CompressionFormat {
+        self.compression_options.compression_format
+    }
+
+    #[must_use]
+    pub fn compression_level(&self) -> CompressionLevel {
+        self.compression_options.compression_level
+    }
+
+    #[must_use]
+    pub fn compression_result(&self) -> CompressionResult {
+        self.compression_result
+    }
+
+    #[must_use]
+    pub fn format(&self) -> Format {
+        self.format
+    }
+
+    #[must_use]
+    pub fn mip_chunk_height(&self) -> usize {
+        self.mip_chunk_height
+    }
+
+    #[must_use]
+    pub fn mip_chunk_width(&self) -> usize {
+        self.mip_chunk_width
+    }
+}
+
+impl Default for ReadOptions {
+    fn default() -> Self {
+        Self {
+            format: Format::default(),
+            mip_chunk_width: 512,
+            mip_chunk_height: 512,
+            compression_options: ChunkCompressionOptions::default(),
+            compression_result: CompressionResult::default(),
+        }
+    }
+}
+
+impl From<ArchiveOptions> for ReadOptions {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for ReadOptions {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self {
+            format: value.format(),
+            compression_options: value.into(),
+            ..Default::default()
+        }
+    }
+}
+
+/// See also [`FileWriteOptions`](WriteOptions).
+#[derive(Debug, Default)]
+#[repr(transparent)]
+pub struct WriteOptionsBuilder(WriteOptions);
+
+impl WriteOptionsBuilder {
+    #[must_use]
+    pub fn build(self) -> WriteOptions {
+        self.0
+    }
+
+    #[must_use]
+    pub fn compression_format(mut self, compression_format: CompressionFormat) -> Self {
+        self.0.compression_format = compression_format;
+        self
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+}
+
+impl From<ArchiveOptions> for WriteOptionsBuilder {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for WriteOptionsBuilder {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self(value.into())
+    }
+}
+
+/// Common parameters to configure how files are written.
+///
+/// ```rust
+/// use ba2::fo4::{CompressionFormat, FileWriteOptions, Format};
+///
+/// // Write a file for FO4/FO76
+/// let _ = FileWriteOptions::builder()
+///     .compression_format(CompressionFormat::Zip)
+///     .build();
+///
+/// // Write a file for SF, GNRL format
+/// let _ = FileWriteOptions::builder()
+///     .compression_format(CompressionFormat::Zip)
+///     .build();
+///
+/// // Write a file for SF, DX10 format
+/// let _ = FileWriteOptions::builder()
+///     .compression_format(CompressionFormat::LZ4)
+///     .build();
+/// ```
+#[derive(Clone, Copy, Debug, Default)]
+pub struct WriteOptions {
+    compression_format: CompressionFormat,
+}
+
+impl WriteOptions {
+    #[must_use]
+    pub fn builder() -> WriteOptionsBuilder {
+        WriteOptionsBuilder::new()
+    }
+
+    #[must_use]
+    pub fn compression_format(&self) -> CompressionFormat {
+        self.compression_format
+    }
+}
+
+impl From<ArchiveOptions> for WriteOptions {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for WriteOptions {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self {
+            compression_format: value.compression_format(),
+        }
+    }
+}
+
+/// File header for DX10 archives.
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub struct DX10 {
+    pub height: u16,
+    pub width: u16,
+    pub mip_count: u8,
+    pub format: u8,
+    pub flags: u8,
+    pub tile_mode: u8,
+}
+
+/// File header for GNMF archives.
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub struct GNMF {
+    /// See [here](https://github.com/tge-was-taken/GFD-Studio/blob/dad6c2183a6ec0716c3943b71991733bfbd4649d/GFDLibrary/Textures/GNF/GNFTexture.cs#L529-L536) for more info.
+    pub metadata: [u32; 8],
+}
+
+/// Optionally present file header.
+///
+/// The header variant must match the archive [`Format`] when writing.
+#[allow(clippy::upper_case_acronyms)]
+#[derive(Clone, Debug, Default, Eq, PartialEq)]
+pub enum Header {
+    #[default]
+    GNRL,
+    DX10(DX10),
+    GNMF(GNMF),
+}
+
+impl From<DX10> for Header {
+    fn from(value: DX10) -> Self {
+        Self::DX10(value)
+    }
+}
+
+impl From<GNMF> for Header {
+    fn from(value: GNMF) -> Self {
+        Self::GNMF(value)
+    }
+}
+
+type Container<'bytes> = Vec<Chunk<'bytes>>;
+
+/// Represents a file within the FO4 virtual filesystem.
+#[derive(Clone, Debug, Default)]
+pub struct File<'bytes> {
+    pub(crate) chunks: Container<'bytes>,
+    pub header: Header,
+}
+
+impl<'bytes> Sealed for File<'bytes> {}
+
+type ReadResult<T> = T;
+derive::reader_with_options!((File: ReadOptions) => ReadResult);
+
+impl<'bytes> File<'bytes> {
+    #[must_use]
+    pub fn as_mut_ptr(&mut self) -> *mut Chunk<'bytes> {
+        self.chunks.as_mut_ptr()
+    }
+
+    #[must_use]
+    pub fn as_mut_slice(&mut self) -> &mut [Chunk<'bytes>] {
+        self.chunks.as_mut_slice()
+    }
+
+    #[must_use]
+    pub fn as_ptr(&self) -> *const Chunk<'bytes> {
+        self.chunks.as_ptr()
+    }
+
+    #[must_use]
+    pub fn as_slice(&self) -> &[Chunk<'bytes>] {
+        self.chunks.as_slice()
+    }
+
+    pub fn clear(&mut self) {
+        self.chunks.clear();
+    }
+
+    /// # Panics
+    ///
+    /// Panics if [`start_bound`](RangeBounds::start_bound) exceeds [`end_bound`](RangeBounds::end_bound), or if [`end_bound`](RangeBounds::end_bound) exceeds [`len`](Self::len).
+    pub fn drain<R>(&mut self, range: R) -> impl Iterator<Item = Chunk<'bytes>> + '_
+    where
+        R: RangeBounds<usize>,
+    {
+        self.chunks.drain(range)
+    }
+
+    /// # Panics
+    ///
+    /// Panics if `index` exceeds [`len`](Self::len), or [`is_full`](Self::is_full).
+    pub fn insert(&mut self, index: usize, element: Chunk<'bytes>) {
+        self.try_insert(index, element).unwrap();
+    }
+
+    #[must_use]
+    pub fn is_empty(&self) -> bool {
+        self.chunks.is_empty()
+    }
+
+    #[must_use]
+    pub fn is_full(&self) -> bool {
+        self.len() >= 4
+    }
+
+    pub fn iter(&self) -> impl Iterator<Item = &Chunk<'bytes>> {
+        self.chunks.iter()
+    }
+
+    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Chunk<'bytes>> {
+        self.chunks.iter_mut()
+    }
+
+    #[must_use]
+    pub fn len(&self) -> usize {
+        self.chunks.len()
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    pub fn pop(&mut self) -> Option<Chunk<'bytes>> {
+        self.chunks.pop()
+    }
+
+    /// # Panics
+    ///
+    /// Panics if [`is_full`](Self::is_full).
+    pub fn push(&mut self, element: Chunk<'bytes>) {
+        self.try_push(element).unwrap();
+    }
+
+    #[must_use]
+    pub fn remaining_capacity(&self) -> usize {
+        4usize.saturating_sub(self.len())
+    }
+
+    /// # Panics
+    ///
+    /// Panics if `index` exceeds [`len`](Self::len).
+    pub fn remove(&mut self, index: usize) -> Chunk<'bytes> {
+        self.chunks.remove(index)
+    }
+
+    pub fn retain_mut<F>(&mut self, f: F)
+    where
+        F: FnMut(&mut Chunk<'bytes>) -> bool,
+    {
+        self.chunks.retain_mut(f);
+    }
+
+    /// # Panics
+    ///
+    /// Panics if `index` exceeds [`len`](Self::len), or [`is_empty`](Self::is_empty).
+    pub fn swap_remove(&mut self, index: usize) -> Chunk<'bytes> {
+        self.try_swap_remove(index).unwrap()
+    }
+
+    pub fn truncate(&mut self, len: usize) {
+        self.chunks.truncate(len);
+    }
+
+    /// # Panics
+    ///
+    /// Panics if `index` exceeds [`len`](Self::len).
+    pub fn try_insert(
+        &mut self,
+        index: usize,
+        element: Chunk<'bytes>,
+    ) -> result::Result<(), CapacityError<'bytes>> {
+        if self.is_full() {
+            Err(CapacityError(element))
+        } else {
+            self.do_reserve();
+            self.chunks.insert(index, element);
+            Ok(())
+        }
+    }
+
+    pub fn try_push(
+        &mut self,
+        element: Chunk<'bytes>,
+    ) -> result::Result<(), CapacityError<'bytes>> {
+        if self.is_full() {
+            Err(CapacityError(element))
+        } else {
+            self.do_reserve();
+            self.chunks.push(element);
+            Ok(())
+        }
+    }
+
+    /// # Panics
+    ///
+    /// Panics if `index` exceeds [`len`](Self::len).
+    pub fn try_swap_remove(&mut self, index: usize) -> Option<Chunk<'bytes>> {
+        if index < self.len() {
+            Some(self.chunks.swap_remove(index))
+        } else {
+            None
+        }
+    }
+
+    pub fn write<Out>(&self, stream: &mut Out, options: &WriteOptions) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let mut sink = Sink::new(stream);
+        match &self.header {
+            Header::GNRL => self.write_gnrl(&mut sink, *options)?,
+            Header::DX10(x) => self.write_dx10(&mut sink, *options, *x)?,
+            Header::GNMF(x) => self.write_gnmf(&mut sink, *options, x)?,
+        }
+
+        Ok(())
+    }
+
+    fn do_reserve(&mut self) {
+        match self.len() {
+            0 | 3 => self.chunks.reserve_exact(1),
+            1 => self.chunks.reserve_exact(3),
+            2 => self.chunks.reserve_exact(2),
+            _ => (),
+        }
+    }
+
+    fn do_read<In>(stream: &mut In, options: &ReadOptions) -> Result<Self>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let mut this = match options.format {
+            Format::GNRL => Self::read_gnrl(stream),
+            Format::DX10 => Self::read_dx10(stream, options),
+            Format::GNMF => Err(Error::NotImplemented),
+        }?;
+
+        if options.compression_result == CompressionResult::Compressed {
+            for chunk in &mut this {
+                *chunk = chunk.compress(&options.compression_options)?;
+            }
+        }
+
+        Ok(this)
+    }
+
+    fn read_dx10<In>(stream: &In, options: &ReadOptions) -> Result<Self>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let scratch =
+            ScratchImage::load_dds(stream.as_bytes(), DDS_FLAGS::DDS_FLAGS_NONE, None, None)?;
+        let meta = scratch.metadata();
+        let is_cubemap = meta.is_cubemap();
+        let header: Header = DX10 {
+            height: meta.height.try_into()?,
+            width: meta.width.try_into()?,
+            mip_count: meta.mip_levels.try_into()?,
+            format: meta.format.bits().try_into()?,
+            flags: is_cubemap.into(),
+            tile_mode: 8,
+        }
+        .into();
+
+        let images = scratch.images();
+        let chunk_from_mips = |range: Range<usize>| -> Result<Chunk> {
+            let try_clamp = |num: usize| -> Result<u16> {
+                let result = usize::min(meta.mip_levels.saturating_sub(1), num).try_into()?;
+                Ok(result)
+            };
+            let mips = try_clamp(range.start)?..=try_clamp(range.end - 1)?;
+            let mut bytes = Vec::new();
+            for image in &images[range] {
+                let ptr = NonNull::new(image.pixels).unwrap_or(NonNull::dangling());
+                let pixels = unsafe { slice::from_raw_parts(ptr.as_ptr(), image.slice_pitch) };
+                bytes.extend_from_slice(pixels);
+            }
+            Ok(Chunk {
+                // dxtex always allocates internally, so we have to copy bytes and use from_owned here
+                bytes: CompressableBytes::from_owned(bytes.into(), None),
+                mips: Some(mips),
+            })
+        };
+
+        let chunks = if let Some(images_len) = NonZeroUsize::new(images.len()) {
+            if is_cubemap {
+                // don't chunk cubemaps
+                let chunk = chunk_from_mips(0..images_len.get())?;
+                [chunk].into_iter().collect()
+            } else {
+                let pitch = meta.format.compute_pitch(
+                    options.mip_chunk_width,
+                    options.mip_chunk_height,
+                    CP_FLAGS::CP_FLAGS_NONE,
+                )?;
+
+                let mut v = Vec::with_capacity(4);
+                let mut size = 0;
+                let mut start = 0;
+                let mut stop = 0;
+                loop {
+                    let image = &images[stop];
+                    if size == 0 || size + image.slice_pitch < pitch.slice {
+                        size += image.slice_pitch;
+                    } else {
+                        let chunk = chunk_from_mips(start..stop)?;
+                        v.push(chunk);
+                        start = stop;
+                        size = image.slice_pitch;
+                    }
+
+                    if v.len() == 3 {
+                        break;
+                    }
+
+                    stop += 1;
+                    if stop == images_len.get() {
+                        break;
+                    }
+                }
+
+                if stop < images_len.get() {
+                    let chunk = chunk_from_mips(stop..images_len.get())?;
+                    v.push(chunk);
+                } else {
+                    let chunk = chunk_from_mips(start..stop)?;
+                    v.push(chunk);
+                }
+
+                debug_assert!(v.len() <= 4);
+                v
+            }
+        } else {
+            Vec::new()
+        };
+
+        Ok(Self { chunks, header })
+    }
+
+    #[allow(clippy::unnecessary_wraps)]
+    fn read_gnrl<In>(stream: &mut In) -> Result<Self>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let bytes = stream.read_bytes_to_end().into_compressable(None);
+        let chunk = Chunk { bytes, mips: None };
+        Ok([chunk].into_iter().collect())
+    }
+
+    fn write_dx10<Out>(
+        &self,
+        stream: &mut Sink<Out>,
+        options: WriteOptions,
+        dx10: DX10,
+    ) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let meta = TexMetadata {
+            width: dx10.width.into(),
+            height: dx10.height.into(),
+            depth: 1,
+            array_size: 1,
+            mip_levels: dx10.mip_count.into(),
+            misc_flags: if (dx10.flags & 1) == 0 {
+                0
+            } else {
+                #[allow(clippy::useless_conversion)]
+                {
+                    TEX_MISC_FLAG::TEX_MISC_TEXTURECUBE.bits().try_into()?
+                }
+            },
+            misc_flags2: 0,
+            format: u32::from(dx10.format).into(),
+            dimension: TEX_DIMENSION::TEX_DIMENSION_TEXTURE2D,
+        };
+
+        let header = meta.encode_dds_header(DDS_FLAGS::DDS_FLAGS_NONE)?;
+        stream.write_bytes(&header)?;
+        self.write_gnrl(stream, options)
+    }
+
+    fn write_gnmf<Out>(
+        &self,
+        stream: &mut Sink<Out>,
+        options: WriteOptions,
+        gnmf: &GNMF,
+    ) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        const ALIGNMENT: u8 = 0x8;
+
+        let body = {
+            const ALIGN: usize = ALIGNMENT as usize;
+            let len = {
+                let len: usize = self
+                    .iter()
+                    .map(|x| x.decompressed_len().unwrap_or_else(|| x.len()))
+                    .sum();
+                let extra = len % ALIGN;
+                if extra == 0 {
+                    len
+                } else {
+                    len - extra + ALIGN
+                }
+            };
+
+            let mut buffer = Vec::with_capacity(len);
+            let mut stream = Sink::new(&mut buffer);
+            self.write_gnrl(&mut stream, options)?;
+
+            let extra = buffer.len() % ALIGN;
+            if extra != 0 {
+                buffer.resize_with(buffer.len() - extra + ALIGN, Default::default);
+            }
+
+            buffer
+        };
+
+        let header = {
+            const HEADER_SIZE: u32 = 0x100;
+            let magic = cc::make_four(b"GNF ");
+            let contents_size: u32 = HEADER_SIZE - 0x8;
+            let version: u8 = 2;
+            let texture_count: u8 = 1;
+            let alignment: u8 = ALIGNMENT;
+            let stream_size: u32 = HEADER_SIZE
+                .checked_add(body.len().try_into()?)
+                .ok_or(Error::IntegralOverflow)?;
+
+            let mut buffer = Vec::with_capacity(HEADER_SIZE as usize);
+            let mut stream = Sink::new(&mut buffer);
+
+            stream.write(
+                &(
+                    magic,
+                    contents_size,
+                    version,
+                    texture_count,
+                    alignment,
+                    0u8,
+                    stream_size,
+                ),
+                Endian::Little,
+            )?;
+            stream.write(&gnmf.metadata, Endian::Little)?;
+
+            buffer.resize_with(HEADER_SIZE as usize, Default::default);
+            buffer
+        };
+
+        stream.write_bytes(&header)?;
+        stream.write_bytes(&body)?;
+        Ok(())
+    }
+
+    fn write_gnrl<Out>(&self, stream: &mut Sink<Out>, options: WriteOptions) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let mut buf = Vec::new();
+        let options = ChunkCompressionOptions::builder()
+            .compression_format(options.compression_format)
+            .build();
+
+        for chunk in self {
+            let bytes = if chunk.is_compressed() {
+                buf.clear();
+                chunk.decompress_into(&mut buf, &options)?;
+                &buf
+            } else {
+                chunk.as_bytes()
+            };
+            stream.write_bytes(bytes)?;
+        }
+
+        Ok(())
+    }
+}
+
+impl<'bytes> Index<usize> for File<'bytes> {
+    type Output = Chunk<'bytes>;
+
+    fn index(&self, index: usize) -> &Self::Output {
+        &self.chunks[index]
+    }
+}
+
+impl<'bytes> IndexMut<usize> for File<'bytes> {
+    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+        &mut self.chunks[index]
+    }
+}
+
+impl<'bytes> FromIterator<Chunk<'bytes>> for File<'bytes> {
+    fn from_iter<T>(iter: T) -> Self
+    where
+        T: IntoIterator<Item = Chunk<'bytes>>,
+    {
+        let chunks: Vec<_> = iter.into_iter().collect();
+        assert!(chunks.len() <= 4);
+        Self {
+            chunks,
+            header: Header::default(),
+        }
+    }
+}
+
+impl<'bytes> IntoIterator for File<'bytes> {
+    type Item = <Container<'bytes> as IntoIterator>::Item;
+    type IntoIter = <Container<'bytes> as IntoIterator>::IntoIter;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.chunks.into_iter()
+    }
+}
+
+impl<'bytes, 'this> IntoIterator for &'this File<'bytes> {
+    type Item = <&'this Container<'bytes> as IntoIterator>::Item;
+    type IntoIter = <&'this Container<'bytes> as IntoIterator>::IntoIter;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.chunks.iter()
+    }
+}
+
+impl<'bytes, 'this> IntoIterator for &'this mut File<'bytes> {
+    type Item = <&'this mut Container<'bytes> as IntoIterator>::Item;
+    type IntoIter = <&'this mut Container<'bytes> as IntoIterator>::IntoIter;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.chunks.iter_mut()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::fo4::File;
+
+    #[test]
+    fn default_state() {
+        let f = File::default();
+        assert!(f.is_empty());
+        assert!(f.as_slice().is_empty());
+        assert!(!f.is_full());
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/fo4/hashing.rs.html b/src/ba2/fo4/hashing.rs.html new file mode 100644 index 0000000..aa57332 --- /dev/null +++ b/src/ba2/fo4/hashing.rs.html @@ -0,0 +1,791 @@ +hashing.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+
use crate::{derive, hashing};
+use bstr::{BStr, BString, ByteSlice as _};
+
+// archives aren't sorted in any particular order, so we can just default these
+/// The underlying hash object used to uniquely identify objects within the archive.
+#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
+#[repr(C)]
+pub struct Hash {
+    /// The file's stem crc.
+    pub file: u32,
+    /// The first 4 bytes of the file's extension.
+    pub extension: u32,
+    /// The file's parent path crc.
+    pub directory: u32,
+}
+
+derive::hash!(FileHash);
+
+impl Hash {
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+}
+
+#[allow(clippy::unreadable_literal)]
+#[must_use]
+fn crc32(bytes: &[u8]) -> u32 {
+    const LUT: [u32; 256] = [
+        0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
+        0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
+        0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
+        0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+        0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
+        0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
+        0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
+        0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+        0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
+        0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
+        0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
+        0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+        0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
+        0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
+        0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
+        0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+        0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
+        0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+        0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
+        0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+        0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
+        0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
+        0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
+        0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+        0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
+        0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
+        0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
+        0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+        0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
+        0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+        0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
+        0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+        0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
+        0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
+        0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
+        0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+        0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
+    ];
+
+    let mut crc: u32 = 0;
+    for &b in bytes {
+        crc = crc.wrapping_shr(8) ^ LUT[((crc ^ u32::from(b)) & 0xFF) as usize];
+    }
+    crc
+}
+
+struct Split<'string> {
+    parent: &'string BStr,
+    stem: &'string BStr,
+    extension: &'string BStr,
+}
+
+#[must_use]
+fn split_path(path: &BStr) -> Split<'_> {
+    let stem_pos = path.iter().rposition(|&x| x == b'\\');
+    let parent = stem_pos.map(|pos| &path[0..pos]).unwrap_or_default();
+
+    let extension_pos = path.iter().rposition(|&x| x == b'.');
+    let extension = extension_pos
+        .and_then(|pos| path.get(pos + 1..)) // don't include '.'
+        .unwrap_or_default()
+        .as_bstr();
+
+    let first = stem_pos.map_or(0, |x| x + 1);
+    let last = extension_pos.unwrap_or(path.len());
+    let stem = path.get(first..last).unwrap_or_default().as_bstr();
+
+    Split {
+        parent,
+        stem,
+        extension,
+    }
+}
+
+/// Produces a hash using the given path.
+#[must_use]
+pub fn hash_file(path: &BStr) -> (FileHash, BString) {
+    let mut path = path.to_owned();
+    (hash_file_in_place(&mut path), path)
+}
+
+/// Produces a hash using the given path.
+///
+/// The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.
+#[must_use]
+pub fn hash_file_in_place(path: &mut BString) -> FileHash {
+    hashing::normalize_path(path);
+    let pieces = split_path(path.as_ref());
+
+    let mut h = Hash {
+        file: crc32(pieces.stem),
+        extension: 0,
+        directory: crc32(pieces.parent),
+    };
+
+    // truncation is impossible here
+    #[allow(clippy::cast_possible_truncation)]
+    let len = { usize::min(pieces.extension.len(), 4) as u32 };
+    for i in 0..len {
+        h.extension |= u32::from(pieces.extension[i as usize]) << (i * 8);
+    }
+
+    h.into()
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::fo4::{self, Hash};
+    use bstr::ByteSlice as _;
+
+    #[test]
+    fn default_state() {
+        let h = Hash::default();
+        assert_eq!(h.file, 0);
+        assert_eq!(h.extension, 0);
+        assert_eq!(h.directory, 0);
+    }
+
+    #[test]
+    fn validate_hashes() {
+        let l = |path: &[u8]| fo4::hash_file(path.as_bstr()).0;
+        let r = |file: u32, extension: u32, directory: u32| Hash {
+            file,
+            extension,
+            directory,
+        };
+
+        assert_eq!(
+            l(b"Sound\\Voice\\Fallout4.esm\\RobotMrHandy\\Mar\xEDa_M.fuz"),
+            r(0xC9FB26F9, 0x007A7566, 0x8A9C014E)
+        );
+        assert_eq!(
+            l(br"Strings\ccBGSFO4001-PipBoy(Black)_en.DLSTRINGS"),
+            r(0x1985075C, 0x74736C64, 0x29F6B58B)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\BGSFO4001\AnimObjects\PipBoy\PipBoy02(Black)_d.DDS"),
+            r(0x69E1E82C, 0x00736464, 0x23157A84)
+        );
+        assert_eq!(
+            l(br"Materials\CreationClub\BGSFO4003\AnimObjects\PipBoy\PipBoyLabels01(Camo01).BGSM"),
+            r(0x0785843B, 0x6D736762, 0x818374CC)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\BGSFO4003\AnimObjects\PipBoy\PipBoy02(Camo01)_d.DDS"),
+            r(0xF2D2F9A7, 0x00736464, 0xE9DB0C08)
+        );
+        assert_eq!(
+            l(br"Strings\ccBGSFO4004-PipBoy(Camo02)_esmx.DLSTRINGS"),
+            r(0xC26B77C1, 0x74736C64, 0x29F6B58B)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\BGSFO4004\AnimObjects\PipBoy\PipBoyLabels01(Camo02)_d.DDS"),
+            r(0xB32EE4B0, 0x00736464, 0x089FAA9B)
+        );
+        assert_eq!(
+            l(br"Strings\ccBGSFO4006-PipBoy(Chrome)_es.STRINGS"),
+            r(0xA94A4503, 0x69727473, 0x29F6B58B)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\BGSFO4006\AnimObjects\PipBoy\PipBoy01(Chrome)_s.DDS"),
+            r(0xE2D67EE2, 0x00736464, 0xC251DC17)
+        );
+        assert_eq!(
+            l(br"Meshes\CreationClub\BGSFO4016\Clothes\Prey\MorganSpaceSuit_M_First.nif"),
+            r(0x212E5DAD, 0x0066696E, 0x741DAAC0)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\BGSFO4016\Clothes\Prey\Morgan_Male_Body_s.DDS"),
+            r(0x9C672F34, 0x00736464, 0x1D5F0EDF)
+        );
+        assert_eq!(
+            l(br"Strings\ccBGSFO4018-GaussRiflePrototype_ru.STRINGS"),
+            r(0x5198717F, 0x69727473, 0x29F6B58B)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\BGSFO4018\Weapons\GaussRiflePrototype\Barrel02_s.DDS"),
+            r(0x2C98BAA2, 0x00736464, 0x8D59E9EA)
+        );
+        assert_eq!(
+            l(br"Strings\ccBGSFO4019-ChineseStealthArmor_esmx.DLSTRINGS"),
+            r(0xDDF2A35F, 0x74736C64, 0x29F6B58B)
+        );
+        assert_eq!(l(br"Textures\CreationClub\BGSFO4019\Armor\ChineseStealthArmor\ChineseStealthArmor01_d.DDS"), r(0x03C2AA10, 0x00736464, 0x71ED2818));
+        assert_eq!(
+            l(br"Materials\CreationClub\BGSFO4020\Actors\PowerArmor\T45helmet01(Black).BGSM"),
+            r(0xF56D31C0, 0x6D736762, 0x28A143A5)
+        );
+        assert_eq!(l(br"Textures\CreationClub\BGSFO4020\Actors\PowerArmor\T51\Black\T51Helmet01(Black)_d.DDS"), r(0x3192919D, 0x00736464, 0xA56D1E61));
+        assert_eq!(
+            l(br"Materials\CreationClub\BGSFO4038\Actors\PowerArmor\HorsePAHelmet.BGSM"),
+            r(0xE90B72CC, 0x6D736762, 0x44676566)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\BGSFO4038\Actors\PowerArmor\HorsePATorso_teal_d.DDS"),
+            r(0x0A6251B3, 0x00736464, 0xC1AC59B4)
+        );
+        assert_eq!(
+            l(br"Strings\ccBGSFO4044-HellfirePowerArmor_en.DLSTRINGS"),
+            r(0x3E5C1E5E, 0x74736C64, 0x29F6B58B)
+        );
+        assert_eq!(l(br"Textures\CreationClub\BGSFO4044\Actors\PowerArmor\HellfirePAHelmet_Institute_d.DDS"), r(0x0F221EAF, 0x00736464, 0xC021EF40));
+        assert_eq!(
+            l(br"Meshes\Weapons\HandmadeShotgun\HandmadeShotgun_GlowSights.nif"),
+            r(0x4E080CE2, 0x0066696E, 0xCCD47ECF)
+        );
+        assert_eq!(
+            l(br"Textures\Weapons\HandmadeShotgun\HandmadeShotgun_Barrels_GhoulSlayer_d.DDS"),
+            r(0xBBFC484C, 0x00736464, 0xCEAE4154)
+        );
+        assert_eq!(l(br"Materials\CreationClub\FSVFO4001\Clothes\MilitaryBackpack\BackpackPatch_NCR02.bgsm"), r(0x90EB78B9, 0x6D736762, 0xDA685DF4));
+        assert_eq!(l(br"Textures\CreationClub\FSVFO4001\Clothes\MilitaryBackpack\Button_SunsetSars_d.DDS"), r(0xC25F8604, 0x00736464, 0xD1CE178D));
+        assert_eq!(
+            l(br"Materials\CreationClub\FSVFO4002\Furniture\MidCenturyModern01\BedSpread01.bgsm"),
+            r(0xA5AAE799, 0x6D736762, 0xBECD0DEF)
+        );
+        assert_eq!(
+            l(br"Textures\CreationClub\FSVFO4002\Furniture\MidCenturyModern01\Bed01_n.DDS"),
+            r(0x6A09686A, 0x00736464, 0xBA782808)
+        );
+        assert_eq!(
+            l(br"Sound\FX\DLC03\NPC\Gulper\NPC_Gulper_Foot_Walk_02.xwm"),
+            r(0xFE001981, 0x006D7778, 0xE7FBD6C4)
+        );
+        assert_eq!(
+            l(br"Textures\Terrain\DLC03FarHarbor\DLC03FarHarbor.4.-69.41.DDS"),
+            r(0x36BACD03, 0x00736464, 0x8184624D)
+        );
+        assert_eq!(
+            l(br"Sound\Voice\DLCCoast.esm\PlayerVoiceFemale01\00043FFC_1.fuz"),
+            r(0x339EFB3F, 0x007A7566, 0x3A5289D4)
+        );
+        assert_eq!(
+            l(br"Meshes\PreCombined\DLCNukaWorld.esm\0000F616_17EAC297_OC.NIF"),
+            r(0xD4AD97F7, 0x0066696E, 0x0787B7E9)
+        );
+        assert_eq!(
+            l(br"Textures\Terrain\NukaWorld\NukaWorld.4.-28.28_msn.DDS"),
+            r(0x86C13103, 0x00736464, 0x26C08933)
+        );
+        assert_eq!(
+            l(br"Sound\Voice\DLCNukaWorld.esm\DLC04NPCMJohnCalebBradberton\00044D5E_1.fuz"),
+            r(0x896E4419, 0x007A7566, 0xD6575CD6)
+        );
+        assert_eq!(
+            l(br"Meshes\SCOL\DLCRobot.esm\CM00007BD8.NIF"),
+            r(0x103559EF, 0x0066696E, 0xF584B7C4)
+        );
+        assert_eq!(
+            l(br"Textures\DLC01\SetDressing\Rubble\Robottrashpilesnorust_s.DDS"),
+            r(0xC7AF7106, 0x00736464, 0x5FD1A1B0)
+        );
+        assert_eq!(
+            l(br"Sound\Voice\DLCRobot.esm\DLC01RobotCompanionFemaleProcessed\00001460_1.fuz"),
+            r(0x6D3D7DC7, 0x007A7566, 0xB2B47CAD)
+        );
+        assert_eq!(
+            l(br"Materials\DLC02\SetDressing\Workshop\NeonSignage\NeonLetterKit01-Orange-5.BGEM"),
+            r(0x21D59551, 0x6D656762, 0x926F0C27)
+        );
+        assert_eq!(
+            l(br"Textures\DLC02\SetDressing\Workshop\Traps\DLC02_SpringTrap01_s.DDS"),
+            r(0x02BE99A4, 0x00736464, 0xF03CA2DF)
+        );
+        assert_eq!(
+            l(br"Sound\FX\DLC05\PHY\BallTrack\PHY_Metal_BallTrack_SteelBall_Wood_H_03.xwm"),
+            r(0x33AABE0C, 0x006D7778, 0x07AA294C)
+        );
+        assert_eq!(
+            l(br"Textures\DLC05\Effects\PaintBalls\ImpactDecalPaintSplatters01Red_d.DDS"),
+            r(0x6327DF24, 0x00736464, 0xFB5FB431)
+        );
+        assert_eq!(
+            l(br"Meshes\SCOL\DLCworkshop03.esm\CM00001091.NIF"),
+            r(0x2CAF6750, 0x0066696E, 0xABA83647)
+        );
+        assert_eq!(
+            l(br"Textures\DLC06\Interiors\Vault\DLC06VltSignWelcome88_01_d.DDS"),
+            r(0x825BD732, 0x00736464, 0xAE76DDEF)
+        );
+        assert_eq!(
+            l(br"Sound\Voice\DLCworkshop03.esm\FemaleEvenToned\00005232_1.fuz"),
+            r(0x4DB6EE2D, 0x007A7566, 0xDA9F7ABC)
+        );
+        assert_eq!(
+            l(br"Meshes\AnimTextData\DynamicIdleData\5693375383928345500.txt"),
+            r(0x997FC17A, 0x00747874, 0xFD345C50)
+        );
+        assert_eq!(
+            l(br"Interface\Pipboy_StatsPage.swf"),
+            r(0x2F26E4D0, 0x00667773, 0xD2FDF873)
+        );
+        assert_eq!(
+            l(br"Materials\Landscape\Grass\BeachGrass01.BGSM"),
+            r(0xB023CE22, 0x6D736762, 0x941D851F)
+        );
+        assert_eq!(
+            l(br"Meshes\Actors\Character\FaceGenData\FaceGeom\Fallout4.esm\000B3EC7.NIF"),
+            r(0x90C91640, 0x0066696E, 0x067FA81E)
+        );
+        assert_eq!(
+            l(br"Meshes\PreCombined\0000E069_7831AAC9_OC.NIF"),
+            r(0x5F0B19DF, 0x0066696E, 0xE659D075)
+        );
+        assert_eq!(
+            l(br"scripts\MinRadiantOwnedBuildResourceScript.pex"),
+            r(0xA2DAD4FD, 0x00786570, 0x40724840)
+        );
+        assert_eq!(
+            l(br"Meshes\debris\roundrock2_dirt.nif"),
+            r(0x1E47A158, 0x0066696E, 0xF55EC6BA)
+        );
+        assert_eq!(
+            l(br"ShadersFX\Shaders011.fxp"),
+            r(0x883415D8, 0x00707866, 0xDFAE3D0F)
+        );
+        assert_eq!(
+            l(br"Sound\FX\FX\Bullet\Impact\xxx\FX_Bullet_Impact_Dirt_04.xwm"),
+            r(0xFFAD9A14, 0x006D7778, 0xCBA20EB7)
+        );
+        assert_eq!(
+            l(br"Textures\Effects\ColorBlackZeroAlphaUtility.DDS"),
+            r(0xF912F225, 0x00736464, 0xEA3C9738)
+        );
+        assert_eq!(
+            l(br"Textures\interiors\Building\BldWindow01_s.DDS"),
+            r(0x6ECA4F0C, 0x00736464, 0x5A3A7C7A)
+        );
+        assert_eq!(
+            l(br"Textures\Terrain\Commonwealth\Commonwealth.4.-8.12_msn.DDS"),
+            r(0x55E37BD8, 0x00736464, 0x4409E1A9)
+        );
+        assert_eq!(
+            l(br"Textures\Clothes\Nat\Nats_Outfit_s.DDS"),
+            r(0x692FFE7D, 0x00736464, 0x3F5BEDF1)
+        );
+        assert_eq!(
+            l(br"Textures\Interface\Newspaper\Newspaper_s.DDS"),
+            r(0xFAC17C6C, 0x00736464, 0x58B9C5A4)
+        );
+        assert_eq!(
+            l(br"Textures\Actors\Character\FaceCustomization\Fallout4.esm\00110043_s.DDS"),
+            r(0x09A155E6, 0x00736464, 0x9C7DFA7A)
+        );
+        assert_eq!(
+            l(br"Textures\Terrain\Commonwealth\Commonwealth.4.-48.-60.DDS"),
+            r(0x182C2446, 0x00736464, 0x4409E1A9)
+        );
+        assert_eq!(
+            l(br"Textures\Terrain\Commonwealth\Commonwealth.4.-80.8_msn.DDS"),
+            r(0xDA3234A4, 0x00736464, 0x4409E1A9)
+        );
+        assert_eq!(
+            l(br"Textures\Terrain\SanctuaryHillsWorld\SanctuaryHillsWorld.4.-36.40.DDS"),
+            r(0xDD27070A, 0x00736464, 0x49AAA5E1)
+        );
+        assert_eq!(
+            l(br"Textures\Terrain\SanctuaryHillsWorld\SanctuaryHillsWorld.4.76.-24.DDS"),
+            r(0x71560B31, 0x00736464, 0x49AAA5E1)
+        );
+        assert_eq!(
+            l(br"Sound\Voice\Fallout4.esm\NPCMTravisMiles\000A6032_1.fuz"),
+            r(0x34402DE0, 0x007A7566, 0xF186D761)
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/fo4/mod.rs.html b/src/ba2/fo4/mod.rs.html new file mode 100644 index 0000000..e52fc9b --- /dev/null +++ b/src/ba2/fo4/mod.rs.html @@ -0,0 +1,411 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+
#![doc(alias = "fallout 4")]
+#![doc(alias = "starfield")]
+
+//! Fallout 4
+//!
+//! *"Good morning! Vault-Tec calling! ... You can't begin to know how happy I am to finally speak with you. I've been trying for days. It's a matter of utmost urgency, I assure you."*
+//!
+//! This format is the latest iteration, having debuted with Fallout 4. It primarily uses zlib for compression, but Starfield has introduced lz4 into the mix. Unlike previous formats, texture files are now split into chunks to enable streaming mips at a more granular level.
+//!
+//! # Reading
+//! ```rust
+//! use ba2::{
+//!     fo4::{Archive, ArchiveKey, FileWriteOptions},
+//!     prelude::*,
+//! };
+//! use std::{fs, path::Path};
+//!
+//! fn example() -> Option<()> {
+//!     let path = Path::new(r"path/to/fallout4/Data/Fallout4 - Interface.ba2");
+//!     let (archive, meta) = Archive::read(path).ok()?;
+//!     let key: ArchiveKey = b"Interface/HUDMenu.swf".into();
+//!     let file = archive.get(&key)?;
+//!     let mut dst = fs::File::create("HUDMenu.swf").ok()?;
+//!     let options: FileWriteOptions = meta.into();
+//!     file.write(&mut dst, &options).ok()?;
+//!     Some(())
+//! }
+//! ```
+//!
+//! # Writing
+//! ```rust
+//! use ba2::{
+//!     fo4::{Archive, ArchiveKey, ArchiveOptions, Chunk, File},
+//!     prelude::*,
+//! };
+//! use std::fs;
+//!
+//! fn example() -> Option<()> {
+//!     let chunk = Chunk::from_decompressed(b"Hello world!\n");
+//!     let file: File = [chunk].into_iter().collect();
+//!     let key: ArchiveKey = b"hello.txt".into();
+//!     let archive: Archive = [(key, file)].into_iter().collect();
+//!     let mut dst = fs::File::create("example.ba2").ok()?;
+//!     let options = ArchiveOptions::default();
+//!     archive.write(&mut dst, &options).ok()?;
+//!     Some(())
+//! }
+//! ```
+
+mod archive;
+mod chunk;
+mod file;
+mod hashing;
+
+pub use self::{
+    archive::{
+        Archive, Key as ArchiveKey, Options as ArchiveOptions,
+        OptionsBuilder as ArchiveOptionsBuilder,
+    },
+    chunk::{
+        Chunk, CompressionOptions as ChunkCompressionOptions,
+        CompressionOptionsBuilder as ChunkCompressionOptionsBuilder,
+    },
+    file::{
+        CapacityError as FileCapacityError, File, Header as FileHeader,
+        ReadOptions as FileReadOptions, ReadOptionsBuilder as FileReadOptionsBuilder,
+        WriteOptions as FileWriteOptions, WriteOptionsBuilder as FileWriteOptionsBuilder,
+        DX10 as DX10Header, GNMF as GNMFHeader,
+    },
+    hashing::{hash_file, hash_file_in_place, FileHash, Hash},
+};
+
+use core::{convert::Infallible, num::TryFromIntError};
+use directxtex::HResultError;
+use std::io;
+
+#[non_exhaustive]
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+    #[error("can not compress the given file because it is already compressed")]
+    AlreadyCompressed,
+
+    #[error("can not decompress the given file because it is already decompressed")]
+    AlreadyDecompressed,
+
+    #[error("buffer failed to decompress to the expected size... expected {expected} bytes, but got {actual} bytes")]
+    DecompressionSizeMismatch { expected: usize, actual: usize },
+
+    #[error("error while working with a dds file")]
+    DX10(#[from] HResultError),
+
+    #[error(
+        "attempted to write an archive in a format that does not match a file/chunk in the archive"
+    )]
+    FormatMismatch,
+
+    #[doc(hidden)]
+    #[error(transparent)]
+    Infallible(#[from] Infallible),
+
+    #[error("an operation on two integers would have overflowed and corrupted data")]
+    IntegralOverflow,
+
+    #[error("an operation on an integer would have truncated and corrupted data")]
+    IntegralTruncation,
+
+    #[error("invalid sentinel read from chunk: {0}")]
+    InvalidChunkSentinel(u32),
+
+    #[error("invalid chunk size read from file header: {0}")]
+    InvalidChunkSize(u16),
+
+    #[error("invalid format read from archive header: {0}")]
+    InvalidFormat(u32),
+
+    #[error("invalid magic read from archive header: {0}")]
+    InvalidMagic(u32),
+
+    #[error("invalid version read from archive header: {0}")]
+    InvalidVersion(u32),
+
+    #[error(transparent)]
+    Io(#[from] io::Error),
+
+    #[error(transparent)]
+    LZ4(#[from] lzzzz::Error),
+
+    #[error("support for this feature is not yet implemented")]
+    NotImplemented,
+}
+
+impl From<TryFromIntError> for Error {
+    fn from(_: TryFromIntError) -> Self {
+        Self::IntegralTruncation
+    }
+}
+
+pub type Result<T> = core::result::Result<T, Error>;
+
+/// A list of all compression methods supported by the ba2 format.
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub enum CompressionFormat {
+    /// The default compression format, compatible with all games that utilize the ba2 format.
+    #[default]
+    Zip,
+
+    /// A more specialized format leveraging lz4's fast decompression to improve streaming time.
+    ///
+    /// Only compatible with Starfield or later.
+    LZ4,
+}
+
+/// Specifies the compression level to use when compressing data.
+///
+/// Only compatible with [`CompressionFormat::Zip`].
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub enum CompressionLevel {
+    /// Fallout 4.
+    #[default]
+    FO4,
+
+    /// Fallout 4 on the xbox.
+    ///
+    /// Uses a smaller windows size, but higher a compression level to yield a higher compression ratio.
+    FO4Xbox,
+
+    /// Starfield.
+    ///
+    /// Uses a custom DEFLATE algorithm with zlib wrapper to obtain a good compression ratio.
+    SF,
+}
+
+impl CompressionLevel {
+    /// Fallout 76.
+    pub const FO76: Self = Self::FO4;
+}
+
+/// Represents the file format for an archive.
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub enum Format {
+    /// A GNRL archive can contain any kind of file.
+    #[default]
+    GNRL,
+
+    /// A DX10 archive can only contain .dds files (Microsoft DirectX).
+    DX10,
+
+    /// A GNMF archive can only contain .gnf files (Sony GNM).
+    GNMF,
+}
+
+/// Indicates the version of an archive.
+#[allow(non_camel_case_types)]
+#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
+pub enum Version {
+    /// Initial format introduced in Fallout 4.
+    #[default]
+    v1 = 1,
+
+    /// Intoduced in Starfield.
+    v2 = 2,
+
+    /// Intoduced in Starfield.
+    v3 = 3,
+}
+
\ No newline at end of file diff --git a/src/ba2/guess.rs.html b/src/ba2/guess.rs.html new file mode 100644 index 0000000..c92d414 --- /dev/null +++ b/src/ba2/guess.rs.html @@ -0,0 +1,119 @@ +guess.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+
use crate::cc;
+use core::mem;
+use std::io::Read;
+
+/// The file format for a given archive.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum FileFormat {
+    TES3,
+    TES4,
+    FO4,
+}
+
+const BSA: u32 = cc::make_four(b"BSA");
+const BTDX: u32 = cc::make_four(b"BTDX");
+
+/// Guesses the archive format for a given source.
+///
+/// This function does not guarantee that the given source constitutes a well-formed archive of the deduced format. It merely remarks that if the file were a well-formed archive, it would be of the deduced format.
+#[allow(clippy::module_name_repetitions)]
+pub fn guess_format<In>(source: &mut In) -> Option<FileFormat>
+where
+    In: ?Sized + Read,
+{
+    let mut buf = [0u8; mem::size_of::<u32>()];
+    source.read_exact(&mut buf).ok()?;
+    let magic = u32::from_le_bytes(buf);
+    match magic {
+        0x100 => Some(FileFormat::TES3),
+        BSA => Some(FileFormat::TES4),
+        BTDX => Some(FileFormat::FO4),
+        _ => None,
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::FileFormat;
+    use anyhow::Context as _;
+    use std::{fs::File, path::Path};
+
+    #[test]
+    fn guess() -> anyhow::Result<()> {
+        let root = Path::new("data/common_guess_test");
+        let tests = [
+            (FileFormat::TES3, "tes3.bsa"),
+            (FileFormat::TES4, "tes4.bsa"),
+            (FileFormat::FO4, "fo4.ba2"),
+        ];
+
+        for (format, file_name) in tests {
+            let mut file = File::open(root.join(file_name))
+                .with_context(|| format!("failed to open file: {file_name}"))?;
+            let guess = crate::guess_format(&mut file);
+            assert_eq!(guess, Some(format));
+        }
+
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/hashing.rs.html b/src/ba2/hashing.rs.html new file mode 100644 index 0000000..29521be --- /dev/null +++ b/src/ba2/hashing.rs.html @@ -0,0 +1,153 @@ +hashing.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+
use bstr::BString;
+
+#[must_use]
+const fn build_lookup_table() -> [u8; 256] {
+    let mut table = [0u8; u8::MAX as usize + 1];
+    let mut i: u8 = 0;
+    loop {
+        table[i as usize] = i;
+        match i {
+            u8::MAX => break,
+            _ => i += 1,
+        };
+    }
+
+    table['/' as usize] = b'\\';
+
+    let offset = b'a' - b'A';
+    let mut i = b'A';
+    loop {
+        table[i as usize] = i + offset;
+        match i {
+            b'Z' => break,
+            _ => i += 1,
+        };
+    }
+
+    table
+}
+
+#[must_use]
+fn map_byte(b: u8) -> u8 {
+    const LUT: [u8; 256] = build_lookup_table();
+    LUT[b as usize]
+}
+
+pub(crate) fn normalize_path(path: &mut BString) {
+    for b in path.iter_mut() {
+        *b = map_byte(*b);
+    }
+
+    while path.last().is_some_and(|&x| x == b'\\') {
+        path.pop();
+    }
+
+    while path.first().is_some_and(|&x| x == b'\\') {
+        path.remove(0);
+    }
+
+    if path.is_empty() || path.len() >= 260 {
+        path.clear();
+        path.push(b'.');
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::map_byte;
+
+    #[test]
+    fn test_mapping() {
+        macro_rules! test {
+            ($l:literal, $r:literal) => {
+                assert_eq!(map_byte($l as u8), $r as u8);
+            };
+        }
+
+        test!('A', 'a');
+        test!('a', 'a');
+        test!('Z', 'z');
+        test!('z', 'z');
+        test!('/', '\\');
+        test!('\\', '\\');
+        test!('.', '.');
+        test!(255, 255);
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/io.rs.html b/src/ba2/io.rs.html new file mode 100644 index 0000000..029fc26 --- /dev/null +++ b/src/ba2/io.rs.html @@ -0,0 +1,1081 @@ +io.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+
use crate::containers::Bytes;
+use core::{mem, ops::Range};
+use memmap2::{Mmap, MmapOptions};
+use std::{
+    fs::File,
+    io::{self, Write},
+    sync::Arc,
+};
+
+#[derive(Clone, Copy)]
+pub(crate) enum Endian {
+    Little,
+    Big,
+    Native,
+}
+
+pub(crate) trait Source<'bytes> {
+    fn as_bytes(&self) -> &[u8];
+
+    fn read_bytes(&mut self, len: usize) -> io::Result<Bytes<'bytes>>;
+
+    #[must_use]
+    fn read_bytes_to_end(&mut self) -> Bytes<'bytes>;
+
+    fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()>;
+
+    fn seek_absolute(&mut self, pos: usize) -> io::Result<()>;
+
+    #[must_use]
+    fn stream_position(&self) -> usize;
+
+    fn read<T>(&mut self, endian: Endian) -> io::Result<T>
+    where
+        T: BinaryReadable<'bytes, Item = T>,
+    {
+        T::from_stream(self, endian)
+    }
+
+    fn read_protocol<T>(&mut self, endian: Endian) -> io::Result<T::Item>
+    where
+        T: BinaryReadable<'bytes>,
+    {
+        T::from_stream(self, endian)
+    }
+
+    fn save_restore_position<F, T>(&mut self, f: F) -> io::Result<T>
+    where
+        F: FnOnce(&mut Self) -> T,
+    {
+        let position = self.stream_position();
+        let result = f(self);
+        self.seek_absolute(position)?;
+        Ok(result)
+    }
+
+    fn seek_relative(&mut self, offset: isize) -> io::Result<()> {
+        if let Some(pos) = self.stream_position().checked_add_signed(offset) {
+            self.seek_absolute(pos)
+        } else {
+            Err(io::ErrorKind::UnexpectedEof.into())
+        }
+    }
+}
+
+macro_rules! make_sourceable {
+    ($this:ty, $bytes_lifetime:lifetime $(,$this_lifetime:lifetime)?) => {
+        impl $(<$this_lifetime>)? Source<$bytes_lifetime> for $this {
+            fn as_bytes(&self) -> &[u8] {
+                &self.source[..]
+            }
+
+            fn read_into(&mut self, buf: &mut [u8]) -> io::Result<()> {
+                let len = buf.len();
+                let start = self.pos;
+                let stop = start + len;
+                if stop > self.source.len() {
+                    Err(io::ErrorKind::UnexpectedEof.into())
+                } else {
+                    self.pos += len;
+                    buf.copy_from_slice(&self.source[start..stop]);
+                    Ok(())
+                }
+            }
+
+            fn read_bytes(&mut self, len: usize) -> io::Result<Bytes<$bytes_lifetime>> {
+                let start = self.pos;
+                let stop = start + len;
+                if stop > self.source.len() {
+                    Err(io::ErrorKind::UnexpectedEof.into())
+                } else {
+                    self.pos += len;
+                    Ok(self.make_bytes(start..stop))
+                }
+            }
+
+            fn read_bytes_to_end(&mut self) -> Bytes<$bytes_lifetime> {
+                let len = self.source.len();
+                let start = self.pos;
+                let stop = len - start;
+                self.make_bytes(start..stop)
+            }
+
+            fn seek_absolute(&mut self, pos: usize) -> io::Result<()> {
+                if pos > self.source.len() {
+                    Err(io::ErrorKind::UnexpectedEof.into())
+                } else {
+                    self.pos = pos;
+                    Ok(())
+                }
+            }
+
+            fn stream_position(&self) -> usize {
+                self.pos
+            }
+        }
+    };
+}
+
+pub(crate) struct BorrowedSource<'bytes> {
+    source: &'bytes [u8],
+    pos: usize,
+}
+
+impl<'bytes> BorrowedSource<'bytes> {
+    #[must_use]
+    fn make_bytes(&self, range: Range<usize>) -> Bytes<'bytes> {
+        Bytes::from_borrowed(&self.source[range])
+    }
+}
+
+impl<'bytes> From<&'bytes [u8]> for BorrowedSource<'bytes> {
+    fn from(source: &'bytes [u8]) -> Self {
+        Self { source, pos: 0 }
+    }
+}
+
+make_sourceable!(BorrowedSource<'bytes>, 'bytes, 'bytes);
+
+pub(crate) struct CopiedSource<'bytes> {
+    source: &'bytes [u8],
+    pos: usize,
+}
+
+impl<'bytes> CopiedSource<'bytes> {
+    #[must_use]
+    fn make_bytes(&self, range: Range<usize>) -> Bytes<'static> {
+        Bytes::from_owned(self.source[range].into())
+    }
+}
+
+impl<'bytes> From<&'bytes [u8]> for CopiedSource<'bytes> {
+    fn from(source: &'bytes [u8]) -> Self {
+        Self { source, pos: 0 }
+    }
+}
+
+make_sourceable!(CopiedSource<'bytes>, 'static, 'bytes);
+
+pub(crate) struct MappedSource {
+    source: Arc<Mmap>,
+    pos: usize,
+}
+
+impl MappedSource {
+    #[must_use]
+    fn make_bytes(&self, range: Range<usize>) -> Bytes<'static> {
+        Bytes::from_mapped(range.start, range.len(), self.source.clone())
+    }
+}
+
+impl TryFrom<&File> for MappedSource {
+    type Error = io::Error;
+
+    fn try_from(value: &File) -> Result<Self, Self::Error> {
+        let options = MmapOptions::new();
+        let mapping = unsafe { options.map(value) }?;
+        Ok(Self {
+            source: Arc::new(mapping),
+            pos: 0,
+        })
+    }
+}
+
+make_sourceable!(MappedSource, 'static);
+
+pub(crate) trait BinaryReadable<'bytes> {
+    type Item;
+
+    fn from_ne_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        Self::from_stream(stream, Endian::Native)
+    }
+
+    fn from_be_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        Self::from_stream(stream, Endian::Big)
+    }
+
+    fn from_le_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        Self::from_stream(stream, Endian::Little)
+    }
+
+    fn from_stream<In>(stream: &mut In, endian: Endian) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        match endian {
+            Endian::Big => Self::from_be_stream(stream),
+            Endian::Little => Self::from_le_stream(stream),
+            Endian::Native => Self::from_ne_stream(stream),
+        }
+    }
+}
+
+pub(crate) trait BinaryWriteable {
+    type Item: ?Sized;
+
+    fn to_ne_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        Self::to_stream(stream, item, Endian::Native)
+    }
+
+    fn to_be_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        Self::to_stream(stream, item, Endian::Big)
+    }
+
+    fn to_le_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        Self::to_stream(stream, item, Endian::Little)
+    }
+
+    fn to_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item, endian: Endian) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        match endian {
+            Endian::Big => Self::to_be_stream(stream, item),
+            Endian::Little => Self::to_le_stream(stream, item),
+            Endian::Native => Self::to_ne_stream(stream, item),
+        }
+    }
+}
+
+macro_rules! make_binary_streamable {
+    ($t:ty) => {
+        impl<'bytes> BinaryReadable<'bytes> for $t {
+            type Item = $t;
+
+            fn from_be_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                let mut bytes = [0u8; mem::size_of::<Self::Item>()];
+                stream.read_into(&mut bytes)?;
+                Ok(Self::from_be_bytes(bytes))
+            }
+
+            fn from_le_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                let mut bytes = [0u8; mem::size_of::<Self::Item>()];
+                stream.read_into(&mut bytes)?;
+                Ok(Self::from_le_bytes(bytes))
+            }
+
+            fn from_ne_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                let mut bytes = [0u8; mem::size_of::<Self::Item>()];
+                stream.read_into(&mut bytes)?;
+                Ok(Self::from_ne_bytes(bytes))
+            }
+        }
+
+        impl BinaryWriteable for $t {
+            type Item = $t;
+
+            fn to_be_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                let mut bytes = item.to_be_bytes();
+                stream.write_bytes(&mut bytes)
+            }
+
+            fn to_le_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                let mut bytes = item.to_le_bytes();
+                stream.write_bytes(&mut bytes)
+            }
+
+            fn to_ne_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                let mut bytes = item.to_ne_bytes();
+                stream.write_bytes(&mut bytes)
+            }
+        }
+    };
+}
+
+make_binary_streamable!(u8);
+make_binary_streamable!(u16);
+make_binary_streamable!(u32);
+make_binary_streamable!(u64);
+
+make_binary_streamable!(i8);
+make_binary_streamable!(i16);
+make_binary_streamable!(i32);
+make_binary_streamable!(i64);
+
+macro_rules! make_binary_streamable_array {
+    ($n:literal, $($idx:tt $t:ident),+) => {
+        impl<'bytes, T> BinaryReadable<'bytes> for [T; $n]
+        where
+            T: BinaryReadable<'bytes>
+        {
+            type Item = [T::Item; $n];
+
+            fn from_be_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                Ok([$(
+                    $t::from_be_stream(stream)?,
+                )+])
+            }
+
+            fn from_le_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                Ok([$(
+                    $t::from_le_stream(stream)?,
+                )+])
+            }
+
+            fn from_ne_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                Ok([$(
+                    $t::from_ne_stream(stream)?,
+                )+])
+            }
+        }
+
+        impl<'bytes, T> BinaryWriteable for [T; $n]
+        where
+            T: BinaryWriteable,
+            <T as BinaryWriteable>::Item: Sized,
+        {
+            type Item = [T::Item; $n];
+
+            fn to_be_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                $(
+                    $t::to_be_stream(stream, &item[$idx])?;
+                )+
+                Ok(())
+            }
+
+            fn to_le_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                $(
+                    $t::to_le_stream(stream, &item[$idx])?;
+                )+
+                Ok(())
+            }
+
+            fn to_ne_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                $(
+                    $t::to_ne_stream(stream, &item[$idx])?;
+                )+
+                Ok(())
+            }
+        }
+    };
+}
+
+make_binary_streamable_array!( 1, 0 T);
+make_binary_streamable_array!( 2, 0 T, 1 T);
+make_binary_streamable_array!( 3, 0 T, 1 T, 2 T);
+make_binary_streamable_array!( 4, 0 T, 1 T, 2 T, 3 T);
+make_binary_streamable_array!( 5, 0 T, 1 T, 2 T, 3 T, 4 T);
+make_binary_streamable_array!( 6, 0 T, 1 T, 2 T, 3 T, 4 T, 5 T);
+make_binary_streamable_array!( 7, 0 T, 1 T, 2 T, 3 T, 4 T, 5 T, 6 T);
+make_binary_streamable_array!( 8, 0 T, 1 T, 2 T, 3 T, 4 T, 5 T, 6 T, 7 T);
+make_binary_streamable_array!( 9, 0 T, 1 T, 2 T, 3 T, 4 T, 5 T, 6 T, 7 T, 8 T);
+make_binary_streamable_array!(10, 0 T, 1 T, 2 T, 3 T, 4 T, 5 T, 6 T, 7 T, 8 T, 9 T);
+
+macro_rules! make_binary_streamable_tuple {
+    ($($idx:tt $t:ident),+) => {
+        impl<'bytes, $($t,)+> BinaryReadable<'bytes> for ($($t,)+)
+        where
+            $($t: BinaryReadable<'bytes>,)+
+        {
+            type Item = ($($t::Item,)+);
+
+            fn from_be_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                Ok(($(
+                    $t::from_be_stream(stream)?,
+                )+))
+            }
+
+            fn from_le_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                Ok(($(
+                    $t::from_le_stream(stream)?,
+                )+))
+            }
+
+            fn from_ne_stream<In>(stream: &mut In) -> io::Result<Self::Item>
+            where
+                In: ?Sized + Source<'bytes>,
+            {
+                Ok(($(
+                    $t::from_ne_stream(stream)?,
+                )+))
+            }
+        }
+
+        impl<$($t,)+> BinaryWriteable for ($($t,)+)
+        where
+            $(
+                $t: BinaryWriteable,
+                <$t as BinaryWriteable>::Item: Sized,
+            )+
+        {
+            type Item = ($($t::Item,)+);
+
+            fn to_be_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                $(
+                    $t::to_be_stream(stream, &item.$idx)?;
+                )+
+                Ok(())
+            }
+
+            fn to_le_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                $(
+                    $t::to_le_stream(stream, &item.$idx)?;
+                )+
+                Ok(())
+            }
+
+            fn to_ne_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item) -> io::Result<()>
+            where
+                Out: ?Sized + Write,
+            {
+                $(
+                    $t::to_ne_stream(stream, &item.$idx)?;
+                )+
+                Ok(())
+            }
+        }
+    };
+}
+
+make_binary_streamable_tuple!(0 T0);
+make_binary_streamable_tuple!(0 T0, 1 T1);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2, 3 T3);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8);
+make_binary_streamable_tuple!(0 T0, 1 T1, 2 T2, 3 T3, 4 T4, 5 T5, 6 T6, 7 T7, 8 T8, 9 T9);
+
+pub(crate) struct Sink<'stream, Out>
+where
+    Out: ?Sized + Write,
+{
+    stream: &'stream mut Out,
+}
+
+impl<'stream, Out> Sink<'stream, Out>
+where
+    Out: ?Sized + Write,
+{
+    #[must_use]
+    pub(crate) fn new(stream: &'stream mut Out) -> Self {
+        Self { stream }
+    }
+
+    pub(crate) fn write<T>(&mut self, item: &T, endian: Endian) -> io::Result<()>
+    where
+        T: BinaryWriteable<Item = T>,
+    {
+        T::to_stream(self, item, endian)
+    }
+
+    pub(crate) fn write_protocol<T>(&mut self, item: &T::Item, endian: Endian) -> io::Result<()>
+    where
+        T: BinaryWriteable,
+    {
+        T::to_stream(self, item, endian)
+    }
+
+    pub(crate) fn write_bytes(&mut self, bytes: &[u8]) -> io::Result<()> {
+        self.stream.write_all(bytes)
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/lib.rs.html b/src/ba2/lib.rs.html new file mode 100644 index 0000000..9140044 --- /dev/null +++ b/src/ba2/lib.rs.html @@ -0,0 +1,189 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+
//! Archives come in various flavors, and the specific variant you'll need to use depends on which game you're working with. Learn more by choosing one of [`tes3`], [`tes4`], or [`fo4`].
+//!
+//! If you are uncertain of the origins of your archive, then you may use [`guess_format`] to find a starting point.
+//!
+//! # A note on strings
+//! The Creation Engine absolutely does not handle unicode correctly, and even has some nasty, extant bugs which exist related to characters that utilize the extended ascii range. As such, all strings are marked as binary strings, without encoding (see also [`BStr`] or [`BString`]). If you must re-encode strings, then, generally speaking, they are encoded using the system code page of whatever computer happened to write the archive. That means English copies of the game are encoded using Windows-1252, Russian copies using Windows-1251, etc. However, this is not a guarantee and is the source of much consternation when writing internationalized applications for the Creation Engine games.
+
+#![warn(
+    clippy::pedantic,
+    clippy::single_char_lifetime_names,
+    clippy::std_instead_of_core
+)]
+#![allow(
+    unknown_lints,
+    clippy::enum_glob_use,
+    clippy::missing_errors_doc,
+    clippy::struct_field_names
+)]
+
+mod cc;
+mod containers;
+mod derive;
+pub mod fo4;
+mod guess;
+mod hashing;
+mod io;
+mod protocols;
+pub mod tes3;
+pub mod tes4;
+
+pub use guess::{guess_format, FileFormat};
+
+/// Makes a shallow copy of the input.
+///
+/// The lifetime of the result is tied to the input buffer.
+pub struct Borrowed<'borrow>(pub &'borrow [u8]);
+
+/// Makes a deep copy of the input.
+///
+/// The lifetime of the result is independent of the input buffer.
+pub struct Copied<'copy>(pub &'copy [u8]);
+
+mod private {
+    pub trait Sealed {}
+}
+
+use private::Sealed;
+
+/// A trait that enables reading from various sources.
+pub trait Reader<T>: Sealed {
+    type Error;
+    type Item;
+
+    /// Reads an instance of `Self::Item` from the given source.
+    fn read(source: T) -> core::result::Result<Self::Item, Self::Error>;
+}
+
+/// A trait that creates an optionally compressed container using the given value.
+pub trait CompressableFrom<T>: Sealed {
+    /// Makes a compressed instance of `Self` using the given data.
+    #[must_use]
+    fn from_compressed(value: T, decompressed_len: usize) -> Self;
+
+    /// Makes a decompressed instance of `Self` using the given data.
+    #[must_use]
+    fn from_decompressed(value: T) -> Self;
+}
+
+/// Indicates whether the operation should finish by compressing the data or not.
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub enum CompressionResult {
+    /// The data will finish in a compressed state.
+    Compressed,
+    /// The data will finish in a decompressed state.
+    #[default]
+    Decompressed,
+}
+
+/// A trait that enables reading from various sources, with configuration options.
+pub trait ReaderWithOptions<T>: Sealed {
+    type Error;
+    type Item;
+    type Options;
+
+    /// Reads an instance of `Self::Item` from the given source, using the given options.
+    fn read(source: T, options: &Self::Options) -> core::result::Result<Self::Item, Self::Error>;
+}
+
+pub use bstr::{BStr, BString, ByteSlice, ByteVec};
+
+/// Convenience using statements for traits that are needed to work with the library.
+pub mod prelude {
+    pub use crate::{CompressableFrom as _, Reader as _, ReaderWithOptions as _};
+}
+
\ No newline at end of file diff --git a/src/ba2/protocols.rs.html b/src/ba2/protocols.rs.html new file mode 100644 index 0000000..566eb95 --- /dev/null +++ b/src/ba2/protocols.rs.html @@ -0,0 +1,339 @@ +protocols.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+
use crate::{
+    containers::Bytes,
+    io::{BinaryReadable, BinaryWriteable, Endian, Sink, Source},
+};
+use bstr::BStr as ByteStr;
+use core::num::NonZeroU8;
+use std::io::{self, Write};
+
+#[derive(Debug, thiserror::Error)]
+enum Error {
+    #[error("postfix null terminator was missing from a string")]
+    MissingNullTerminator,
+
+    #[error("a string is too large to be written without data loss")]
+    StringTooLarge,
+}
+
+impl From<Error> for io::Error {
+    fn from(value: Error) -> Self {
+        Self::new(io::ErrorKind::InvalidData, value)
+    }
+}
+
+pub(crate) struct BString;
+
+impl<'bytes> BinaryReadable<'bytes> for BString {
+    type Item = Bytes<'bytes>;
+
+    fn from_stream<In>(stream: &mut In, endian: Endian) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let len: u8 = stream.read(endian)?;
+        stream.read_bytes(len.into())
+    }
+}
+
+impl BinaryWriteable for BString {
+    type Item = ByteStr;
+
+    fn to_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item, endian: Endian) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let len: Result<u8, _> = item.len().try_into();
+        match len {
+            Ok(len) => {
+                stream.write(&len, endian)?;
+                stream.write_bytes(item)?;
+                Ok(())
+            }
+            Err(_) => Err(Error::StringTooLarge.into()),
+        }
+    }
+}
+
+pub(crate) struct ZString;
+
+impl<'bytes> BinaryReadable<'bytes> for ZString {
+    type Item = Bytes<'bytes>;
+
+    fn from_stream<In>(stream: &mut In, endian: Endian) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let start = stream.stream_position();
+        let mut len = 0;
+        loop {
+            let byte: u8 = stream.read(endian)?;
+            match byte {
+                0 => break,
+                _ => len += 1,
+            };
+        }
+
+        stream.seek_absolute(start)?;
+        let result = stream.read_bytes(len)?;
+        stream.seek_relative(1)?; // skip null terminator
+        Ok(result)
+    }
+}
+
+impl BinaryWriteable for ZString {
+    type Item = ByteStr;
+
+    fn to_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item, _: Endian) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        stream.write_bytes(item)?;
+        stream.write_bytes(b"\0")?;
+        Ok(())
+    }
+}
+
+pub(crate) struct BZString;
+
+impl<'bytes> BinaryReadable<'bytes> for BZString {
+    type Item = Bytes<'bytes>;
+
+    fn from_stream<In>(stream: &mut In, endian: Endian) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let len: u8 = stream.read(endian)?;
+        let Some(len) = NonZeroU8::new(len) else {
+            return Err(Error::MissingNullTerminator.into());
+        };
+
+        let result = stream.read_bytes((len.get() - 1).into())?;
+        match stream.read(endian)? {
+            b'\0' => Ok(result),
+            _ => Err(Error::MissingNullTerminator.into()),
+        }
+    }
+}
+
+impl BinaryWriteable for BZString {
+    type Item = ByteStr;
+
+    fn to_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item, endian: Endian) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let len: Result<u8, _> = (item.len() + 1).try_into();
+        match len {
+            Ok(len) => {
+                stream.write(&len, endian)?;
+                stream.write_bytes(item)?;
+                stream.write_bytes(b"\0")?;
+                Ok(())
+            }
+            Err(_) => Err(Error::StringTooLarge.into()),
+        }
+    }
+}
+
+pub(crate) struct WString;
+
+impl<'bytes> BinaryReadable<'bytes> for WString {
+    type Item = Bytes<'bytes>;
+
+    fn from_stream<In>(stream: &mut In, endian: Endian) -> io::Result<Self::Item>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let len: u16 = stream.read(endian)?;
+        stream.read_bytes(len.into())
+    }
+}
+
+impl BinaryWriteable for WString {
+    type Item = ByteStr;
+
+    fn to_stream<Out>(stream: &mut Sink<Out>, item: &Self::Item, endian: Endian) -> io::Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let len: Result<u16, _> = item.len().try_into();
+        match len {
+            Ok(len) => {
+                stream.write(&len, endian)?;
+                stream.write_bytes(item)?;
+                Ok(())
+            }
+            Err(_) => Err(Error::StringTooLarge.into()),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes3/archive.rs.html b/src/ba2/tes3/archive.rs.html new file mode 100644 index 0000000..c0a04ea --- /dev/null +++ b/src/ba2/tes3/archive.rs.html @@ -0,0 +1,845 @@ +archive.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+
use crate::{
+    containers::Bytes,
+    derive,
+    io::{Endian, Sink, Source},
+    protocols::ZString,
+    tes3::{self, Error, File, FileHash, Hash, Result},
+};
+use bstr::BString;
+use std::io::Write;
+
+mod constants {
+    pub(crate) const FILE_ENTRY_SIZE: usize = 0x8;
+    pub(crate) const HASH_SIZE: usize = 0x8;
+    pub(crate) const HEADER_MAGIC: u32 = 0x100;
+    pub(crate) const HEADER_SIZE: usize = 0xC;
+}
+
+struct Offsets {
+    name_offsets: usize,
+    names: usize,
+    hashes: usize,
+    file_data: usize,
+}
+
+struct Header {
+    hash_offset: u32,
+    file_count: u32,
+}
+
+impl Header {
+    #[must_use]
+    fn compute_offsets(&self) -> Offsets {
+        let file_count = self.file_count as usize;
+        let name_offsets = constants::HEADER_SIZE + constants::FILE_ENTRY_SIZE * file_count;
+        let names = name_offsets + 0x4 * file_count;
+        let hashes = constants::HEADER_SIZE + self.hash_offset as usize;
+        let file_data = hashes + constants::HASH_SIZE * file_count;
+        Offsets {
+            name_offsets,
+            names,
+            hashes,
+            file_data,
+        }
+    }
+}
+
+derive::key!(Key: FileHash);
+
+impl<'bytes> Key<'bytes> {
+    #[must_use]
+    fn hash_in_place(name: &mut BString) -> FileHash {
+        tes3::hash_file_in_place(name)
+    }
+}
+
+type ReadResult<T> = T;
+derive::archive! {
+    /// Represents the TES3 revision of the bsa format.
+    Archive => ReadResult
+    Map: (Key: FileHash) => File
+}
+
+impl<'bytes> Archive<'bytes> {
+    pub fn write<Out>(&self, stream: &mut Out) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let mut sink = Sink::new(stream);
+        let header = self.make_header()?;
+        Self::write_header(&mut sink, &header)?;
+        self.write_files(&mut sink)?;
+        self.write_name_offsets(&mut sink)?;
+        self.write_names(&mut sink)?;
+        self.write_hashes(&mut sink)?;
+        self.write_file_data(&mut sink)?;
+
+        Ok(())
+    }
+
+    fn make_header(&self) -> Result<Header> {
+        Ok(Header {
+            file_count: self.map.len().try_into()?,
+            hash_offset: {
+                let names_offset = 0xC * self.map.len();
+                let names_len: usize = self.map.keys().map(|x| x.name().len() + 1).sum();
+                (names_offset + names_len).try_into()?
+            },
+        })
+    }
+
+    fn write_files<Out>(&self, sink: &mut Sink<Out>) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let mut offset: u32 = 0;
+        for file in self.map.values() {
+            let size: u32 = file.bytes.len().try_into()?;
+            sink.write(&(size, offset), Endian::Little)?;
+            offset += size;
+        }
+
+        Ok(())
+    }
+
+    fn write_file_data<Out>(&self, sink: &mut Sink<Out>) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        for file in self.map.values() {
+            sink.write_bytes(file.as_bytes())?;
+        }
+
+        Ok(())
+    }
+
+    fn write_hashes<Out>(&self, sink: &mut Sink<Out>) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        for key in self.map.keys() {
+            let hash = &key.hash();
+            sink.write(&(hash.lo, hash.hi), Endian::Little)?;
+        }
+
+        Ok(())
+    }
+
+    fn write_header<Out>(sink: &mut Sink<Out>, header: &Header) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        sink.write(
+            &(
+                constants::HEADER_MAGIC,
+                header.hash_offset,
+                header.file_count,
+            ),
+            Endian::Little,
+        )?;
+        Ok(())
+    }
+
+    fn write_name_offsets<Out>(&self, sink: &mut Sink<Out>) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let mut offset: u32 = 0;
+        for key in self.map.keys() {
+            sink.write(&offset, Endian::Little)?;
+            offset += u32::try_from(key.name().len() + 1)?;
+        }
+
+        Ok(())
+    }
+
+    fn write_names<Out>(&self, sink: &mut Sink<Out>) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        for key in self.map.keys() {
+            sink.write_protocol::<ZString>(key.name(), Endian::Little)?;
+        }
+
+        Ok(())
+    }
+
+    fn do_read<In>(source: &mut In) -> Result<ReadResult<Self>>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let header = Self::read_header(source)?;
+        let offsets = header.compute_offsets();
+        let mut map = Map::default();
+
+        for i in 0..header.file_count as usize {
+            let (key, value) = Self::read_file(source, i, &offsets)?;
+            map.insert(key, value);
+        }
+
+        Ok(Self { map })
+    }
+
+    fn read_file<In>(
+        source: &mut In,
+        idx: usize,
+        offsets: &Offsets,
+    ) -> Result<(Key<'bytes>, File<'bytes>)>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let hash = source.save_restore_position(|source| -> Result<Hash> {
+            source.seek_absolute(offsets.hashes + constants::HASH_SIZE * idx)?;
+            Self::read_hash(source)
+        })??;
+
+        let name = source.save_restore_position(|source| -> Result<Bytes<'bytes>> {
+            source.seek_absolute(offsets.name_offsets + 0x4 * idx)?;
+            let offset: u32 = source.read(Endian::Little)?;
+            source.seek_absolute(offsets.names + offset as usize)?;
+            let name = source.read_protocol::<ZString>(Endian::Little)?;
+            Ok(name)
+        })??;
+
+        let (size, offset): (u32, u32) = source.read(Endian::Little)?;
+        let container = source.save_restore_position(|source| -> Result<Bytes<'bytes>> {
+            source.seek_absolute(offsets.file_data + offset as usize)?;
+            let result = source.read_bytes(size as usize)?;
+            Ok(result)
+        })??;
+
+        Ok((
+            Key {
+                hash: hash.into(),
+                name,
+            },
+            File { bytes: container },
+        ))
+    }
+
+    fn read_hash<In>(source: &mut In) -> Result<Hash>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let (lo, hi) = source.read(Endian::Little)?;
+        Ok(Hash { lo, hi })
+    }
+
+    fn read_header<In>(source: &mut In) -> Result<Header>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let (magic, hash_offset, file_count) = source.read(Endian::Little)?;
+        match magic {
+            constants::HEADER_MAGIC => Ok(Header {
+                hash_offset,
+                file_count,
+            }),
+            _ => Err(Error::InvalidMagic(magic)),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        prelude::*,
+        tes3::{Archive, ArchiveKey, Error, File, FileHash, Hash},
+        Borrowed,
+    };
+    use anyhow::Context as _;
+    use bstr::BString;
+    use memmap2::Mmap;
+    use std::{
+        ffi::OsStr,
+        fs,
+        io::{self, Read as _},
+        path::Path,
+    };
+    use walkdir::WalkDir;
+
+    #[test]
+    fn default_state() -> anyhow::Result<()> {
+        let bsa = Archive::new();
+        assert!(bsa.is_empty());
+        assert!(bsa.len() == 0);
+        Ok(())
+    }
+
+    #[test]
+    fn invalid_magic() -> anyhow::Result<()> {
+        let path = Path::new("data/tes3_invalid_test/invalid_magic.bsa");
+        match Archive::read(path) {
+            Err(Error::InvalidMagic(0x200)) => Ok(()),
+            Err(err) => Err(err.into()),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_out_of_bounds() -> anyhow::Result<()> {
+        let path = Path::new("data/tes3_invalid_test/invalid_exhausted.bsa");
+        match Archive::read(path) {
+            Err(Error::Io(io)) => {
+                assert_eq!(io.kind(), io::ErrorKind::UnexpectedEof);
+                Ok(())
+            }
+            Err(err) => Err(err.into()),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn reading() -> anyhow::Result<()> {
+        let root_path = Path::new("data/tes3_read_test/");
+        let archive = {
+            let archive_path = root_path.join("test.bsa");
+            Archive::read(archive_path.as_path())
+                .with_context(|| format!("failed to read from archive: {archive_path:?}"))?
+        };
+
+        for file_path in WalkDir::new(root_path) {
+            if let Ok(file_path) = file_path {
+                let metadata = file_path
+                    .metadata()
+                    .context("failed to get file path metadata")?;
+                if metadata.is_file() && file_path.path().extension() != Some(OsStr::new("bsa")) {
+                    let key = file_path
+                        .path()
+                        .strip_prefix(root_path)
+                        .with_context(|| {
+                            format!(
+                                "failed to strip prefix ({root_path:?}) from path ({file_path:?})"
+                            )
+                        })?
+                        .as_os_str();
+                    let file = archive
+                        .get(&ArchiveKey::from(key.as_encoded_bytes()))
+                        .with_context(|| format!("failed to get file with key: {key:?}"))?;
+                    assert_eq!(file.len() as u64, metadata.len());
+
+                    let mut original_data = Vec::new();
+                    fs::File::open(file_path.path())
+                        .with_context(|| format!("failed to open file: {file_path:?}"))?
+                        .read_to_end(&mut original_data)
+                        .with_context(|| format!("failed to read from file: {file_path:?}"))?;
+                    assert_eq!(file.as_bytes(), &original_data[..]);
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    #[test]
+    fn writing() -> anyhow::Result<()> {
+        struct Info {
+            key: ArchiveKey<'static>,
+            path: &'static Path,
+        }
+
+        impl Info {
+            fn new(lo: u32, hi: u32, path: &'static str) -> Self {
+                let hash = Hash { lo, hi };
+                let key = ArchiveKey::from(path);
+                assert_eq!(&hash, key.hash());
+                Self {
+                    key,
+                    path: Path::new(path),
+                }
+            }
+        }
+
+        let infos = [
+            Info::new(0x0C18356B, 0xA578DB74, "Tiles/tile_0001.png"),
+            Info::new(0x1B0D3416, 0xF5D5F30E, "Share/License.txt"),
+            Info::new(0x1B3B140A, 0x07B36E53, "Background/background_middle.png"),
+            Info::new(0x29505413, 0x1EB4CED7, "Construct 3/Pixel Platformer.c3p"),
+            Info::new(0x4B7D031B, 0xD4701AD4, "Tilemap/characters_packed.png"),
+            Info::new(0x74491918, 0x2BEBCD0A, "Characters/character_0001.png"),
+        ];
+
+        let mmapped = {
+            let mut result = Vec::<Mmap>::new();
+            for info in &infos {
+                let file_path = Path::new("data/tes3_write_test/data").join(info.path);
+                let fd = fs::File::open(file_path.clone())
+                    .with_context(|| format!("failed to open file: {file_path:?}"))?;
+                let file = unsafe {
+                    Mmap::map(&fd)
+                        .with_context(|| format!("failed to memory map file: {file_path:?}"))?
+                };
+                result.push(file);
+            }
+            result
+        };
+
+        let stream = {
+            let mut archive = Archive::new();
+            for (data, info) in mmapped.iter().zip(&infos) {
+                let file: File = data[..].into();
+                assert!(archive.insert(info.key.clone(), file).is_none());
+            }
+            let mut result = Vec::<u8>::new();
+            archive
+                .write(&mut result)
+                .context("failed to write test archive to memory")?;
+            result
+        };
+
+        let archive =
+            Archive::read(Borrowed(&stream)).context("failed to read from archive in memory")?;
+        for (data, info) in mmapped.iter().zip(&infos) {
+            let file = archive.get(info.key.hash()).with_context(|| {
+                format!("failed to get value from archive with key: {:?}", info.path)
+            })?;
+            assert_eq!(file.as_bytes(), &data[..]);
+        }
+
+        Ok(())
+    }
+
+    #[test]
+    fn assert_generic_interfaces_compile() -> anyhow::Result<()> {
+        let mut bsa = Archive::default();
+        let key = ArchiveKey::default();
+        let hash = FileHash::default();
+
+        _ = bsa.get(&key);
+        _ = bsa.get(&hash);
+
+        _ = bsa.remove(&key);
+        _ = bsa.remove(&hash);
+
+        _ = bsa.remove_entry(&key);
+        _ = bsa.remove_entry(&hash);
+
+        _ = bsa.insert(key, Default::default());
+        _ = bsa.insert(BString::default(), Default::default());
+
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes3/file.rs.html b/src/ba2/tes3/file.rs.html new file mode 100644 index 0000000..9e3c263 --- /dev/null +++ b/src/ba2/tes3/file.rs.html @@ -0,0 +1,145 @@ +file.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+
use crate::{
+    containers::Bytes,
+    derive,
+    io::Source,
+    tes3::{Error, Result},
+};
+use std::io::Write;
+
+/// Represents a file within the TES3 virtual filesystem.
+#[derive(Clone, Debug, Default)]
+pub struct File<'bytes> {
+    pub(crate) bytes: Bytes<'bytes>,
+}
+
+type ReadResult<T> = T;
+derive::bytes!(File);
+derive::reader!(File => ReadResult);
+
+impl<'bytes> File<'bytes> {
+    pub fn write<Out>(&self, stream: &mut Out) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        stream.write_all(self.as_bytes())?;
+        Ok(())
+    }
+
+    #[allow(clippy::unnecessary_wraps)]
+    fn do_read<In>(stream: &mut In) -> Result<ReadResult<Self>>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        Ok(Self {
+            bytes: stream.read_bytes_to_end(),
+        })
+    }
+}
+
+impl<'bytes, const N: usize> From<&'bytes [u8; N]> for File<'bytes> {
+    fn from(value: &'bytes [u8; N]) -> Self {
+        Self::from(value.as_slice())
+    }
+}
+
+impl<'bytes> From<&'bytes [u8]> for File<'bytes> {
+    fn from(value: &'bytes [u8]) -> Self {
+        Self {
+            bytes: Bytes::from_borrowed(value),
+        }
+    }
+}
+
+impl From<Box<[u8]>> for File<'static> {
+    fn from(value: Box<[u8]>) -> Self {
+        Self {
+            bytes: Bytes::from_owned(value),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tes3::File;
+
+    #[test]
+    fn default_state() {
+        let f = File::new();
+        assert!(f.is_empty());
+        assert!(f.len() == 0);
+        assert!(f.as_bytes().is_empty());
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes3/hashing.rs.html b/src/ba2/tes3/hashing.rs.html new file mode 100644 index 0000000..ef77482 --- /dev/null +++ b/src/ba2/tes3/hashing.rs.html @@ -0,0 +1,273 @@ +hashing.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+
use crate::{derive, hashing};
+use bstr::{BStr, BString};
+use core::cmp::Ordering;
+
+/// The underlying hash object used to uniquely identify objects within the archive.
+#[derive(Clone, Copy, Debug, Default)]
+#[repr(C)]
+pub struct Hash {
+    pub lo: u32,
+    pub hi: u32,
+}
+
+derive::hash!(FileHash);
+
+impl Hash {
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    #[allow(clippy::identity_op, clippy::erasing_op)]
+    #[must_use]
+    pub fn numeric(&self) -> u64 {
+        (u64::from(self.hi) << (0 * 8)) | (u64::from(self.lo) << (4 * 8))
+    }
+}
+
+impl PartialEq for Hash {
+    fn eq(&self, other: &Self) -> bool {
+        self.numeric() == other.numeric()
+    }
+}
+
+impl Eq for Hash {}
+
+impl PartialOrd for Hash {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Hash {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.numeric().cmp(&other.numeric())
+    }
+}
+
+/// Produces a hash using the given path.
+#[must_use]
+pub fn hash_file(path: &BStr) -> (FileHash, BString) {
+    let mut path = path.to_owned();
+    (hash_file_in_place(&mut path), path)
+}
+
+/// Produces a hash using the given path.
+///
+/// The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.
+#[must_use]
+pub fn hash_file_in_place(path: &mut BString) -> FileHash {
+    hashing::normalize_path(path);
+    let midpoint = path.len() / 2;
+    let mut h = Hash::new();
+    let mut i: usize = 0;
+
+    // rotate between first 4 bytes
+    while i < midpoint {
+        h.lo ^= u32::from(path[i]) << ((i % 4) * 8);
+        i += 1;
+    }
+
+    // rotate between last 4 bytes
+    while i < path.len() {
+        let rot = u32::from(path[i]) << (((i - midpoint) % 4) * 8);
+        h.hi = u32::rotate_right(h.hi ^ rot, rot);
+        i += 1;
+    }
+
+    h.into()
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tes3::{self, Hash};
+    use bstr::ByteSlice as _;
+
+    #[test]
+    fn hashes_start_empty() {
+        let h: Hash = Default::default();
+        assert_eq!(h.lo, 0);
+        assert_eq!(h.hi, 0);
+        assert_eq!(h.numeric(), 0);
+    }
+
+    #[test]
+    fn validate_hashing() {
+        let hash = |x: &[u8]| tes3::hash_file(x.as_bstr()).0.numeric();
+        assert_eq!(
+            hash(b"meshes/c/artifact_bloodring_01.nif"),
+            0x1C3C1149920D5F0C
+        );
+        assert_eq!(
+            hash(b"meshes/x/ex_stronghold_pylon00.nif"),
+            0x20250749ACCCD202
+        );
+        assert_eq!(hash(b"meshes/r/xsteam_centurions.kf"), 0x6E5C0F3125072EA6);
+        assert_eq!(hash(b"textures/tx_rock_cave_mu_01.dds"), 0x58060C2FA3D8F759);
+        assert_eq!(hash(b"meshes/f/furn_ashl_chime_02.nif"), 0x7C3B2F3ABFFC8611);
+        assert_eq!(hash(b"textures/tx_rope_woven.dds"), 0x5865632F0C052C64);
+        assert_eq!(hash(b"icons/a/tx_templar_skirt.dds"), 0x46512A0B60EDA673);
+        assert_eq!(hash(b"icons/m/misc_prongs00.dds"), 0x51715677BBA837D3);
+        assert_eq!(
+            hash(b"meshes/i/in_c_stair_plain_tall_02.nif"),
+            0x2A324956BF89B1C9
+        );
+        assert_eq!(hash(b"meshes/r/xkwama worker.nif"), 0x6D446E352C3F5A1E);
+    }
+
+    #[test]
+    fn forward_slashes_are_same_as_back_slashes() {
+        let hash = |x: &[u8]| tes3::hash_file(x.as_bstr()).0;
+        assert_eq!(hash(b"foo/bar/baz"), hash(b"foo\\bar\\baz"));
+    }
+
+    #[test]
+    fn hashes_are_case_insensitive() {
+        let hash = |x: &[u8]| tes3::hash_file(x.as_bstr()).0;
+        assert_eq!(hash(b"FOO/BAR/BAZ"), hash(b"foo/bar/baz"));
+    }
+
+    #[test]
+    fn sort_order() {
+        let lhs = Hash { lo: 0, hi: 1 };
+        let rhs = Hash { lo: 1, hi: 0 };
+        assert!(lhs < rhs);
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes3/mod.rs.html b/src/ba2/tes3/mod.rs.html new file mode 100644 index 0000000..ba99be4 --- /dev/null +++ b/src/ba2/tes3/mod.rs.html @@ -0,0 +1,157 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+
#![doc(alias = "morrowind")]
+
+//! TES III: Morrowind
+//!
+//!  *"Ahh yes, we've been expecting you. You'll have to be recorded before you're officially released. There are a few ways we can do this, and the choice is yours."*
+//!
+//! This format debuted and sunset with Morrowind. It is the simplest of all the formats, using no compression or special tricks to organize the data.
+//!
+//! # Reading
+//! ```rust
+//! use ba2::{
+//!     prelude::*,
+//!     tes3::{Archive, ArchiveKey},
+//! };
+//! use std::{fs, path::Path};
+//!
+//! fn example() -> Option<()> {
+//!     let path = Path::new("path/to/morrowind/Data Files/Morrowind.bsa");
+//!     let archive = Archive::read(path).ok()?;
+//!     let key: ArchiveKey = b"icons/gold.dds".into();
+//!     let file = archive.get(&key)?;
+//!     let mut dst = fs::File::create("gold.dds").ok()?;
+//!     file.write(&mut dst).ok()?;
+//!     Some(())
+//! }
+//! ```
+//!
+//! # Writing
+//! ```rust
+//! use ba2::{
+//!     prelude::*,
+//!     tes3::{Archive, ArchiveKey, File},
+//! };
+//! use std::fs;
+//!
+//! fn example() -> Option<()> {
+//!     let file: File = b"Hello world!\n".into();
+//!     let key: ArchiveKey = b"hello.txt".into();
+//!     let archive: Archive = [(key, file)].into_iter().collect();
+//!     let mut dst = fs::File::create("example.bsa").ok()?;
+//!     archive.write(&mut dst).ok()?;
+//!     Some(())
+//! }
+//! ```
+
+mod archive;
+mod file;
+mod hashing;
+
+pub use self::{
+    archive::{Archive, Key as ArchiveKey},
+    file::File,
+    hashing::{hash_file, hash_file_in_place, FileHash, Hash},
+};
+
+use core::num::TryFromIntError;
+use std::io;
+
+#[non_exhaustive]
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+    #[error("an operation on an integer would have truncated and corrupted data")]
+    IntegralTruncation,
+
+    #[error("invalid magic read from archive header: {0}")]
+    InvalidMagic(u32),
+
+    #[error(transparent)]
+    Io(#[from] io::Error),
+}
+
+impl From<TryFromIntError> for Error {
+    fn from(_: TryFromIntError) -> Self {
+        Self::IntegralTruncation
+    }
+}
+
+pub type Result<T> = core::result::Result<T, Error>;
+
\ No newline at end of file diff --git a/src/ba2/tes4/archive.rs.html b/src/ba2/tes4/archive.rs.html new file mode 100644 index 0000000..51f6eee --- /dev/null +++ b/src/ba2/tes4/archive.rs.html @@ -0,0 +1,2667 @@ +archive.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+
use crate::{
+    containers::{Bytes, CompressableBytes},
+    derive,
+    io::{Endian, Sink, Source},
+    protocols::{self, BZString, ZString},
+    tes4::{
+        self, directory::Map as DirectoryMap, Directory, DirectoryHash, DirectoryKey, Error, File,
+        Hash, Result, Version,
+    },
+};
+use bstr::{BStr, BString, ByteSlice as _};
+use core::mem;
+use std::{borrow::Cow, io::Write};
+
+bitflags::bitflags! {
+    /// Archive flags can impact the layout of an archive, or how it is read.
+    #[repr(transparent)]
+    #[derive(Clone, Copy, Debug, Eq, PartialEq)]
+    pub struct Flags: u32 {
+        /// Includes directory paths within the archive.
+        ///
+        /// `archive.exe` does not let you write archives without this flag set.
+        ///
+        /// This includes only the parent path of all files, and not filenames.
+        const DIRECTORY_STRINGS = 1 << 0;
+
+        /// Includes filenames within the archive.
+        ///
+        /// `archive.exe` does not let you write archives without this flag set.
+        ///
+        /// This includes only the filename of all files, and not the parent path.
+        const FILE_STRINGS = 1 << 1;
+
+        /// Compresses the data within the archive.
+        ///
+        /// * The v103 format uses zlib.
+        /// * The v104 format uses xmem and zlib.
+        /// * The v105 format uses lz4.
+        const COMPRESSED = 1 << 2;
+
+        /// Impacts runtime parsing.
+        const RETAIN_DIRECTORY_NAMES = 1 << 3;
+
+        /// Impacts runtime parsing.
+        const RETAIN_FILE_NAMES = 1 << 4;
+
+        /// Impacts runtime parsing.
+        const RETAIN_FILE_NAME_OFFSETS = 1 << 5;
+
+        /// Writes the archive in the xbox (big-endian) format.
+        ///
+        /// This flag affects the sort order of files on disk.
+        ///
+        /// Only the crc hash is actually written in big-endian format.
+        const XBOX_ARCHIVE = 1 << 6;
+
+        /// Impacts runtime parsing.
+        const RETAIN_STRINGS_DURING_STARTUP = 1 << 7;
+
+        /// Writes the full (virtual) path of a file next to the data blob.
+        ///
+        /// This flag has a different meaning in the v103 format.
+        const EMBEDDED_FILE_NAMES = 1 << 8;
+
+        /// Uses the xmem codec from XNA 4.0 to compress the archive.
+        ///
+        /// This flag requires [`Self::compressed`] to be set as well.
+        ///
+        /// This flag is unused in SSE.
+        const XBOX_COMPRESSED = 1 << 9;
+
+        const _ = !0;
+    }
+}
+
+impl Default for Flags {
+    fn default() -> Self {
+        Self::DIRECTORY_STRINGS | Self::FILE_STRINGS
+    }
+}
+
+impl Flags {
+    #[must_use]
+    pub fn directory_strings(&self) -> bool {
+        self.contains(Self::DIRECTORY_STRINGS)
+    }
+
+    #[must_use]
+    pub fn file_strings(&self) -> bool {
+        self.contains(Self::FILE_STRINGS)
+    }
+
+    #[must_use]
+    pub fn compressed(&self) -> bool {
+        self.contains(Self::COMPRESSED)
+    }
+
+    #[must_use]
+    pub fn retain_directory_names(&self) -> bool {
+        self.contains(Self::RETAIN_DIRECTORY_NAMES)
+    }
+
+    #[must_use]
+    pub fn retain_file_names(&self) -> bool {
+        self.contains(Self::RETAIN_FILE_NAMES)
+    }
+
+    #[must_use]
+    pub fn retain_file_name_offsets(&self) -> bool {
+        self.contains(Self::RETAIN_FILE_NAME_OFFSETS)
+    }
+
+    #[must_use]
+    pub fn xbox_archive(&self) -> bool {
+        self.contains(Self::XBOX_ARCHIVE)
+    }
+
+    #[must_use]
+    pub fn retain_strings_during_startup(&self) -> bool {
+        self.contains(Self::RETAIN_STRINGS_DURING_STARTUP)
+    }
+
+    #[must_use]
+    pub fn embedded_file_names(&self) -> bool {
+        self.contains(Self::EMBEDDED_FILE_NAMES)
+    }
+
+    #[must_use]
+    pub fn xbox_compressed(&self) -> bool {
+        self.contains(Self::XBOX_COMPRESSED)
+    }
+}
+
+bitflags::bitflags! {
+    /// Specifies file types contained within an archive.
+    ///
+    /// It's not apparent if the game actually uses these flags for anything.
+    #[repr(transparent)]
+    #[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+    pub struct Types: u16 {
+        const MESHES = 1 << 0;
+        const TEXTURES = 1 << 1;
+        const MENUS = 1 << 2;
+        const SOUNDS = 1 << 3;
+        const VOICES = 1 << 4;
+        const SHADERS = 1 << 5;
+        const TREES = 1 << 6;
+        const FONTS = 1 << 7;
+        const MISC = 1 << 8;
+        const _ = !0;
+    }
+}
+
+impl Types {
+    #[must_use]
+    pub fn meshes(&self) -> bool {
+        self.contains(Self::MESHES)
+    }
+
+    #[must_use]
+    pub fn textures(&self) -> bool {
+        self.contains(Self::TEXTURES)
+    }
+
+    #[must_use]
+    pub fn menus(&self) -> bool {
+        self.contains(Self::MENUS)
+    }
+
+    #[must_use]
+    pub fn sounds(&self) -> bool {
+        self.contains(Self::SOUNDS)
+    }
+
+    #[must_use]
+    pub fn voices(&self) -> bool {
+        self.contains(Self::VOICES)
+    }
+
+    #[must_use]
+    pub fn shaders(&self) -> bool {
+        self.contains(Self::SHADERS)
+    }
+
+    #[must_use]
+    pub fn trees(&self) -> bool {
+        self.contains(Self::TREES)
+    }
+
+    #[must_use]
+    pub fn fonts(&self) -> bool {
+        self.contains(Self::FONTS)
+    }
+
+    #[must_use]
+    pub fn misc(&self) -> bool {
+        self.contains(Self::MISC)
+    }
+}
+
+mod constants {
+    use crate::cc;
+
+    pub(crate) const BSA: u32 = cc::make_four(b"BSA");
+
+    pub(crate) const HEADER_SIZE: u32 = 0x24;
+    pub(crate) const DIRECTORY_ENTRY_SIZE_X86: usize = 0x10;
+    pub(crate) const DIRECTORY_ENTRY_SIZE_X64: usize = 0x18;
+    pub(crate) const FILE_ENTRY_SIZE: usize = 0x10;
+
+    pub(crate) const FILE_FLAG_COMPRESSION: u32 = 1 << 30;
+    pub(crate) const FILE_FLAG_CHECKED: u32 = 1 << 31;
+    pub(crate) const FILE_FLAG_SECONDARY_ARCHIVE: u32 = 1 << 31;
+}
+
+struct Offsets {
+    file_entries: usize,
+    file_names: usize,
+    file_data: usize,
+}
+
+struct Header {
+    version: Version,
+    archive_flags: Flags,
+    directory_count: u32,
+    file_count: u32,
+    directory_names_len: u32,
+    file_names_len: u32,
+    archive_types: Types,
+}
+
+impl Header {
+    #[must_use]
+    fn hash_endian(&self) -> Endian {
+        if self.archive_flags.xbox_archive() {
+            Endian::Big
+        } else {
+            Endian::Little
+        }
+    }
+
+    #[must_use]
+    fn compute_offsets(&self) -> Offsets {
+        let file_entries = {
+            let directory_entries = constants::HEADER_SIZE as usize;
+            let directory_entry_size = match self.version {
+                Version::v103 | Version::v104 => constants::DIRECTORY_ENTRY_SIZE_X86,
+                Version::v105 => constants::DIRECTORY_ENTRY_SIZE_X64,
+            };
+            directory_entries + (directory_entry_size * self.directory_count as usize)
+        };
+
+        let file_names = {
+            let directory_names_len = if self.archive_flags.directory_strings() {
+                // directory names are stored using a bzstring
+                // directory_names_len includes the length of the string + the null terminator,
+                // but not the prefix length byte, so we add directory_count to include it
+                self.directory_names_len as usize + self.directory_count as usize
+            } else {
+                0
+            };
+            file_entries
+                + (directory_names_len + constants::FILE_ENTRY_SIZE * self.file_count as usize)
+        };
+
+        let file_data = if self.archive_flags.file_strings() {
+            file_names + self.file_names_len as usize
+        } else {
+            file_names
+        };
+
+        Offsets {
+            file_entries,
+            file_names,
+            file_data,
+        }
+    }
+}
+
+struct SortedFile<'this, 'bytes> {
+    key: &'this DirectoryKey<'bytes>,
+    this: &'this File<'bytes>,
+    embedded_name: Option<Cow<'this, BStr>>,
+}
+
+struct SortedDirectory<'this, 'bytes> {
+    key: &'this Key<'bytes>,
+    this: &'this Directory<'bytes>,
+    files: Vec<SortedFile<'this, 'bytes>>,
+}
+
+derive::key!(Key: DirectoryHash);
+
+impl<'bytes> Key<'bytes> {
+    #[must_use]
+    fn hash_in_place(name: &mut BString) -> DirectoryHash {
+        tes4::hash_directory_in_place(name)
+    }
+}
+
+/// See also [`ArchiveOptions`](Options).
+#[derive(Debug, Default)]
+#[repr(transparent)]
+pub struct OptionsBuilder(Options);
+
+impl OptionsBuilder {
+    #[must_use]
+    pub fn build(self) -> Options {
+        self.0
+    }
+
+    #[must_use]
+    pub fn flags(mut self, flags: Flags) -> Self {
+        self.0.flags = flags;
+        self
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    #[must_use]
+    pub fn types(mut self, types: Types) -> Self {
+        self.0.types = types;
+        self
+    }
+
+    #[must_use]
+    pub fn version(mut self, version: Version) -> Self {
+        self.0.version = version;
+        self
+    }
+}
+
+#[derive(Clone, Copy, Debug, Default)]
+pub struct Options {
+    version: Version,
+    flags: Flags,
+    types: Types,
+}
+
+impl Options {
+    #[must_use]
+    pub fn builder() -> OptionsBuilder {
+        OptionsBuilder::new()
+    }
+
+    #[must_use]
+    pub fn flags(&self) -> Flags {
+        self.flags
+    }
+
+    #[must_use]
+    pub fn types(&self) -> Types {
+        self.types
+    }
+
+    #[must_use]
+    pub fn version(&self) -> Version {
+        self.version
+    }
+}
+
+type ReadResult<T> = (T, Options);
+derive::archive! {
+    /// Represents the TES4 revision of the bsa format.
+    Archive => ReadResult
+    Map: (Key: DirectoryHash) => Directory
+}
+
+impl<'bytes> Archive<'bytes> {
+    pub fn write<Out>(&self, stream: &mut Out, options: &Options) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        let mut sink = Sink::new(stream);
+        let header = self.make_header(*options)?;
+        Self::write_header(&mut sink, &header)?;
+
+        let offsets = header.compute_offsets();
+        let directories = self.sort_for_write(*options);
+
+        // let mut file_entries_offset = offsets.file_entries + header.file_names_len;
+        let mut file_entries_offset = u32::try_from(offsets.file_entries)?
+            .checked_add(header.file_names_len)
+            .ok_or(Error::IntegralOverflow)?;
+        for directory in &directories {
+            Self::write_directory_entry(
+                &mut sink,
+                *options,
+                directory.key,
+                directory.this,
+                &mut file_entries_offset,
+            )?;
+        }
+
+        let mut file_data_offset = u32::try_from(offsets.file_data)?;
+        for directory in &directories {
+            if options.flags.directory_strings() {
+                sink.write_protocol::<BZString>(directory.key.name(), Endian::Little)?;
+            }
+            for file in &directory.files {
+                Self::write_file_entry(
+                    &mut sink,
+                    *options,
+                    file.key,
+                    file.this,
+                    &mut file_data_offset,
+                    file.embedded_name.as_ref().map(AsRef::as_ref),
+                )?;
+            }
+        }
+
+        if options.flags.file_strings() {
+            for directory in &directories {
+                for file in &directory.files {
+                    sink.write_protocol::<ZString>(file.key.name(), Endian::Little)?;
+                }
+            }
+        }
+
+        for directory in &directories {
+            for file in &directory.files {
+                Self::write_file_data(
+                    &mut sink,
+                    file.this,
+                    file.embedded_name.as_ref().map(AsRef::as_ref),
+                )?;
+            }
+        }
+
+        Ok(())
+    }
+
+    fn make_header(&self, options: Options) -> Result<Header> {
+        #[derive(Default)]
+        struct Info {
+            count: usize,
+            names_len: usize,
+        }
+
+        let mut files = Info::default();
+        let mut directories = Info::default();
+
+        for directory in self {
+            directories.count += 1;
+            if options.flags.directory_strings() {
+                // zstring -> include null terminator
+                directories.names_len += directory.0.name().len() + 1;
+            }
+
+            for file in directory.1 {
+                files.count += 1;
+                if options.flags.file_strings() {
+                    // zstring -> include null terminator
+                    files.names_len += file.0.name().len() + 1;
+                }
+            }
+        }
+
+        Ok(Header {
+            version: options.version,
+            archive_flags: options.flags,
+            directory_count: directories.count.try_into()?,
+            file_count: files.count.try_into()?,
+            directory_names_len: directories.names_len.try_into()?,
+            file_names_len: files.names_len.try_into()?,
+            archive_types: options.types,
+        })
+    }
+
+    fn concat_directory_and_file_name<'string>(
+        directory: &'string Key<'bytes>,
+        file: &'string DirectoryKey<'bytes>,
+    ) -> Cow<'string, BStr> {
+        let directory = directory.name();
+        let file = file.name();
+
+        let directory = match directory.len() {
+            0 => b"".as_bstr(),
+            1 => match directory[0] {
+                b'/' | b'\\' | b'.' => b"".as_bstr(),
+                _ => directory,
+            },
+            _ => directory,
+        };
+
+        match (directory.is_empty(), file.is_empty()) {
+            (true, true) => Cow::default(),
+            (true, false) => Cow::from(file),
+            (false, true) => Cow::from(directory),
+            (false, false) => {
+                let string: BString = [directory, b"\\".as_bstr(), file]
+                    .into_iter()
+                    .flat_map(|x| x.as_bytes())
+                    .copied()
+                    .collect::<Vec<_>>()
+                    .into();
+                Cow::from(string)
+            }
+        }
+    }
+
+    fn sort_for_write<'this>(&'this self, options: Options) -> Vec<SortedDirectory<'this, 'bytes>> {
+        let mut directories: Vec<_> = self
+            .iter()
+            .map(|(directory_key, directory)| {
+                let mut files: Vec<_> = directory
+                    .iter()
+                    .map(|(file_key, file)| {
+                        let embedded_name = match options.version {
+                            Version::v104 | Version::v105
+                                if options.flags.embedded_file_names() =>
+                            {
+                                Some(Self::concat_directory_and_file_name(
+                                    directory_key,
+                                    file_key,
+                                ))
+                            }
+                            _ => None,
+                        };
+                        SortedFile {
+                            key: file_key,
+                            this: file,
+                            embedded_name,
+                        }
+                    })
+                    .collect();
+                if options.flags.xbox_archive() {
+                    files.sort_by_key(|x| x.key.hash().numeric().swap_bytes());
+                }
+                SortedDirectory {
+                    key: directory_key,
+                    this: directory,
+                    files,
+                }
+            })
+            .collect();
+        if options.flags.xbox_archive() {
+            directories.sort_by_key(|x| x.key.hash().numeric().swap_bytes());
+        }
+        directories
+    }
+
+    fn write_directory_entry<Out>(
+        sink: &mut Sink<Out>,
+        options: Options,
+        key: &Key<'bytes>,
+        directory: &Directory<'bytes>,
+        file_entries_offset: &mut u32,
+    ) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        Self::write_hash(sink, options, (*key.hash()).into())?;
+
+        let file_count: u32 = directory.len().try_into()?;
+        sink.write(&file_count, Endian::Little)?;
+
+        if options.version == Version::v105 {
+            sink.write(&0u32, Endian::Little)?;
+        }
+
+        sink.write(file_entries_offset, Endian::Little)?;
+
+        if options.version == Version::v105 {
+            sink.write(&0u32, Endian::Little)?;
+        }
+
+        if options.flags.directory_strings() {
+            // bzstring -> include prefix byte and null terminator
+            // file_entries_offset += key.name().len() + 2;
+            *file_entries_offset = file_entries_offset
+                .checked_add((key.name().len() + 2).try_into()?)
+                .ok_or(Error::IntegralOverflow)?;
+        }
+
+        // file_entries_offset += directory.len() * constants::FILE_ENTRY_SIZE;
+        *file_entries_offset = file_entries_offset
+            .checked_add(
+                directory
+                    .len()
+                    .checked_mul(constants::FILE_ENTRY_SIZE)
+                    .ok_or(Error::IntegralOverflow)?
+                    .try_into()?,
+            )
+            .ok_or(Error::IntegralOverflow)?;
+
+        Ok(())
+    }
+
+    fn write_file_data<Out>(
+        sink: &mut Sink<Out>,
+        file: &File<'bytes>,
+        embedded_file_name: Option<&BStr>,
+    ) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        if let Some(name) = embedded_file_name {
+            sink.write_protocol::<protocols::BString>(name, Endian::Little)?;
+        }
+
+        if let Some(len) = file.decompressed_len() {
+            let len: u32 = len.try_into()?;
+            sink.write(&len, Endian::Little)?;
+        }
+
+        sink.write_bytes(file.as_bytes())?;
+        Ok(())
+    }
+
+    fn write_file_entry<Out>(
+        sink: &mut Sink<Out>,
+        options: Options,
+        key: &DirectoryKey<'bytes>,
+        file: &File<'bytes>,
+        file_data_offset: &mut u32,
+        embedded_file_name: Option<&BStr>,
+    ) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        Self::write_hash(sink, options, (*key.hash()).into())?;
+
+        let (size_with_info, size) = {
+            let mut size = file.len();
+            if let Some(name) = embedded_file_name {
+                // include prefix byte
+                size += name.len() + 1;
+            }
+            if file.is_compressed() {
+                size += mem::size_of::<u32>();
+            }
+
+            let size: u32 = size.try_into()?;
+            let masked = size & !(constants::FILE_FLAG_COMPRESSION | constants::FILE_FLAG_CHECKED);
+            if masked != size {
+                return Err(Error::IntegralTruncation);
+            }
+
+            if file.is_compressed() == options.flags.compressed() {
+                (size, masked)
+            } else {
+                (size | constants::FILE_FLAG_COMPRESSION, masked)
+            }
+        };
+        sink.write(&(size_with_info, *file_data_offset), Endian::Little)?;
+
+        // file_data_offset += size;
+        *file_data_offset = file_data_offset
+            .checked_add(size)
+            .ok_or(Error::IntegralOverflow)?;
+
+        Ok(())
+    }
+
+    fn write_hash<Out>(sink: &mut Sink<Out>, options: Options, hash: Hash) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        sink.write(
+            &(hash.last, hash.last2, hash.length, hash.first),
+            Endian::Little,
+        )?;
+
+        let endian = if options.flags.xbox_archive() {
+            Endian::Big
+        } else {
+            Endian::Little
+        };
+        sink.write(&hash.crc, endian)?;
+
+        Ok(())
+    }
+
+    fn write_header<Out>(sink: &mut Sink<Out>, header: &Header) -> Result<()>
+    where
+        Out: ?Sized + Write,
+    {
+        sink.write(
+            &(
+                constants::BSA,
+                header.version as u32,
+                constants::HEADER_SIZE,
+                header.archive_flags.bits(),
+                header.directory_count,
+                header.file_count,
+                header.directory_names_len,
+                header.file_names_len,
+                header.archive_types.bits(),
+                0u16,
+            ),
+            Endian::Little,
+        )?;
+        Ok(())
+    }
+
+    fn do_read<In>(source: &mut In) -> Result<ReadResult<Self>>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let header = Self::read_header(source)?;
+        let mut offsets = header.compute_offsets();
+        let mut map = Map::default();
+
+        for _ in 0..header.directory_count {
+            let (key, value) = Self::read_directory(source, &header, &mut offsets)?;
+            map.insert(key, value);
+        }
+
+        Ok((
+            Self { map },
+            Options {
+                version: header.version,
+                flags: header.archive_flags,
+                types: header.archive_types,
+            },
+        ))
+    }
+
+    fn read_directory<In>(
+        source: &mut In,
+        header: &Header,
+        offsets: &mut Offsets,
+    ) -> Result<(Key<'bytes>, Directory<'bytes>)>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let hash = Self::read_hash(source, header.hash_endian())?;
+        let file_count: u32 = source.read(Endian::Little)?;
+        #[allow(clippy::cast_possible_wrap)]
+        match header.version {
+            Version::v103 | Version::v104 => source.seek_relative(mem::size_of::<u32>() as isize)?,
+            Version::v105 => source.seek_relative((mem::size_of::<u32>() * 3) as isize)?,
+        }
+
+        let mut map = DirectoryMap::default();
+        let (name, directory) = source.save_restore_position(
+            |source| -> Result<(Bytes<'bytes>, Directory<'bytes>)> {
+                source.seek_absolute(offsets.file_entries)?;
+                let mut name = if header.archive_flags.directory_strings() {
+                    Some(source.read_protocol::<BZString>(Endian::Little)?)
+                } else {
+                    None
+                };
+                for _ in 0..file_count {
+                    let (key, value) = Self::read_file_entry(source, header, offsets, &mut name)?;
+                    map.insert(key, value);
+                }
+                offsets.file_entries = source.stream_position();
+                Ok((name.unwrap_or_default(), Directory { map }))
+            },
+        )??;
+
+        Ok((
+            Key {
+                hash: hash.into(),
+                name,
+            },
+            directory,
+        ))
+    }
+
+    fn read_file_entry<In>(
+        source: &mut In,
+        header: &Header,
+        offsets: &mut Offsets,
+        directory_name: &mut Option<Bytes<'bytes>>,
+    ) -> Result<(DirectoryKey<'bytes>, File<'bytes>)>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let hash = Self::read_hash(source, header.hash_endian())?;
+        let (compression_flipped, mut data_size, data_offset) = {
+            let (size, offset): (u32, u32) = source.read(Endian::Little)?;
+            (
+                (size & constants::FILE_FLAG_COMPRESSION) != 0,
+                (size & !(constants::FILE_FLAG_COMPRESSION | constants::FILE_FLAG_CHECKED))
+                    as usize,
+                (offset & !constants::FILE_FLAG_SECONDARY_ARCHIVE) as usize,
+            )
+        };
+
+        let mut name = if header.archive_flags.file_strings() {
+            source.save_restore_position(|source| -> Result<Option<Bytes<'bytes>>> {
+                source.seek_absolute(offsets.file_names)?;
+                let result = source.read_protocol::<ZString>(Endian::Little)?;
+                offsets.file_names = source.stream_position();
+                Ok(Some(result))
+            })??
+        } else {
+            None
+        };
+
+        let container =
+            source.save_restore_position(|source| -> Result<CompressableBytes<'bytes>> {
+                source.seek_absolute(data_offset)?;
+
+                if matches!(header.version,
+                    Version::v104 | Version::v105 if header.archive_flags.embedded_file_names())
+                {
+                    let mut s = source.read_protocol::<protocols::BString>(Endian::Little)?;
+                    data_size -= s.len() + 1; // include prefix byte
+                    if let Some(pos) = s.as_bytes().iter().rposition(|&x| x == b'\\' || x == b'/') {
+                        if directory_name.is_none() {
+                            *directory_name = Some(s.copy_slice(0..pos));
+                        }
+                        s = s.copy_slice(pos + 1..s.len());
+                    }
+                    if name.is_none() {
+                        name = Some(s);
+                    }
+                }
+
+                let decompressed_len =
+                    match (header.archive_flags.compressed(), compression_flipped) {
+                        (true, false) | (false, true) => {
+                            let result: u32 = source.read(Endian::Little)?;
+                            data_size -= mem::size_of::<u32>();
+                            Some(result as usize)
+                        }
+                        (true, true) | (false, false) => None,
+                    };
+
+                let container = source
+                    .read_bytes(data_size)?
+                    .into_compressable(decompressed_len);
+                Ok(container)
+            })??;
+
+        Ok((
+            DirectoryKey {
+                hash: hash.into(),
+                name: name.unwrap_or_default(),
+            },
+            File { bytes: container },
+        ))
+    }
+
+    fn read_hash<In>(source: &mut In, endian: Endian) -> Result<Hash>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let (last, last2, length, first, crc) = source.read(endian)?;
+        Ok(Hash {
+            last,
+            last2,
+            length,
+            first,
+            crc,
+        })
+    }
+
+    fn read_header<In>(source: &mut In) -> Result<Header>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let (
+            magic,
+            version,
+            header_size,
+            archive_flags,
+            directory_count,
+            file_count,
+            directory_names_len,
+            file_names_len,
+            archive_types,
+            padding,
+        ) = source.read(Endian::Little)?;
+        let _: u16 = padding;
+
+        if magic != constants::BSA {
+            return Err(Error::InvalidMagic(magic));
+        }
+
+        let version = match version {
+            103 => Version::v103,
+            104 => Version::v104,
+            105 => Version::v105,
+            _ => return Err(Error::InvalidVersion(version)),
+        };
+
+        if header_size != constants::HEADER_SIZE {
+            return Err(Error::InvalidHeaderSize(header_size));
+        }
+
+        // there probably exist "valid" archives which set extra bits, so it's not worth validating...
+        let archive_flags = Flags::from_bits_truncate(archive_flags);
+        let archive_types = Types::from_bits_truncate(archive_types);
+
+        Ok(Header {
+            version,
+            archive_flags,
+            directory_count,
+            file_count,
+            directory_names_len,
+            file_names_len,
+            archive_types,
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        prelude::*,
+        tes4::{
+            Archive, ArchiveFlags, ArchiveKey, ArchiveOptions, Directory, DirectoryKey, Error,
+            File, FileCompressionOptions, Version,
+        },
+        Borrowed,
+    };
+    use anyhow::Context as _;
+    use memmap2::Mmap;
+    use std::{
+        fs, io,
+        path::{Path, PathBuf},
+    };
+
+    #[test]
+    fn default_state() {
+        let bsa = Archive::new();
+        assert!(bsa.is_empty());
+        assert!(bsa.len() == 0);
+    }
+
+    #[test]
+    fn read_compressed() -> anyhow::Result<()> {
+        let test = |file_name: &str| -> anyhow::Result<()> {
+            let root = Path::new("data/tes4_compression_test");
+
+            let (bsa, options) = Archive::read(root.join(file_name).as_path())
+                .with_context(|| format!("failed to read archive: {file_name}"))?;
+            let compression_options = FileCompressionOptions::builder()
+                .version(options.version)
+                .build();
+
+            let files = ["License.txt", "Preview.png"];
+            for file_name in files {
+                let path = root.join(file_name);
+                let directory = bsa
+                    .get(&ArchiveKey::from(b"."))
+                    .with_context(|| format!("failed to get directory for: {file_name}"))?;
+                let compressed_from_archive = directory
+                    .get(&DirectoryKey::from(file_name))
+                    .with_context(|| format!("failed to get file for: {file_name}"))?;
+                assert!(compressed_from_archive.is_compressed());
+
+                let metadata = fs::metadata(&path)
+                    .with_context(|| format!("failed to get metadata for: {path:?}"))?;
+                let decompressed_len = compressed_from_archive
+                    .decompressed_len()
+                    .with_context(|| format!("file was not compressed: {path:?}"))?
+                    as u64;
+                assert_eq!(decompressed_len, metadata.len());
+
+                let decompressed_from_disk = File::read(path.as_path(), &Default::default())
+                    .with_context(|| format!("failed to read file from disk: {path:?}"))?;
+                let compressed_from_disk = decompressed_from_disk
+                    .compress(&compression_options)
+                    .with_context(|| format!("failed to compress file: {path:?}"))?;
+                assert_eq!(
+                    compressed_from_archive.decompressed_len(),
+                    compressed_from_disk.decompressed_len()
+                );
+
+                let decompressed_from_archive = compressed_from_archive
+                    .decompress(&compression_options)
+                    .with_context(|| format!("failed to decompress file: {file_name}"))?;
+                assert_eq!(
+                    decompressed_from_archive.as_bytes(),
+                    decompressed_from_disk.as_bytes()
+                );
+            }
+
+            Ok(())
+        };
+
+        test("test_104.bsa").context("v104")?;
+        test("test_105.bsa").context("v105")?;
+
+        Ok(())
+    }
+
+    #[test]
+    fn xbox_decompressed_read() -> anyhow::Result<()> {
+        let root = Path::new("data/tes4_xbox_read_test");
+
+        let (normal, normal_options) = Archive::read(root.join("normal.bsa").as_path())
+            .context("failed to read normal archive")?;
+        assert!(!normal_options.flags().xbox_archive());
+        assert!(!normal_options.flags().xbox_compressed());
+        assert!(!normal_options.flags().compressed());
+
+        let (xbox, xbox_options) = Archive::read(root.join("xbox.bsa").as_path())
+            .context("failed to read xbox archive")?;
+        assert!(xbox_options.flags().xbox_archive());
+        assert!(!xbox_options.flags().xbox_compressed());
+        assert!(!xbox_options.flags().compressed());
+
+        assert_eq!(normal.len(), xbox.len());
+        for (directory_normal, directory_xbox) in normal.iter().zip(xbox) {
+            assert_eq!(directory_normal.0.hash(), directory_xbox.0.hash());
+            assert_eq!(directory_normal.0.name(), directory_xbox.0.name());
+            assert_eq!(directory_normal.1.len(), directory_xbox.1.len());
+
+            for (file_normal, file_xbox) in directory_normal.1.iter().zip(directory_xbox.1) {
+                assert_eq!(file_normal.0.hash(), file_xbox.0.hash());
+                assert_eq!(file_normal.0.name(), file_xbox.0.name());
+                assert!(!file_normal.1.is_compressed());
+                assert!(!file_xbox.1.is_compressed());
+                assert_eq!(file_normal.1.len(), file_xbox.1.len());
+                assert_eq!(file_normal.1.as_bytes(), file_xbox.1.as_bytes());
+            }
+        }
+
+        Ok(())
+    }
+
+    #[test]
+    fn xbox_decompressed_write() -> anyhow::Result<()> {
+        let path = Path::new("data/tes4_xbox_write_test/in.bsa");
+
+        let original = {
+            let fd =
+                fs::File::open(path).with_context(|| format!("failed to open file: {path:?}"))?;
+            unsafe { Mmap::map(&fd) }
+                .with_context(|| format!("failed to memory map file: {path:?}"))?
+        };
+
+        let copy = {
+            let (archive, options) =
+                Archive::read(path).with_context(|| format!("failed to read archive: {path:?}"))?;
+            let mut v = Vec::new();
+            archive
+                .write(&mut v, &options)
+                .with_context(|| format!("failed to write archive: {path:?}"))?;
+            v
+        };
+
+        let original = &original[..];
+        let copy = &copy[..];
+        assert_eq!(original.len(), copy.len());
+        assert_eq!(original, copy);
+
+        Ok(())
+    }
+
+    #[test]
+    fn file_compression_diverges_from_archive_compression() -> anyhow::Result<()> {
+        let root = Path::new("data/tes4_compression_mismatch_test");
+        let (bsa, options) =
+            Archive::read(root.join("test.bsa").as_path()).context("failed to read archive")?;
+        assert!(options.flags().compressed());
+
+        let files = ["License.txt", "SampleA.png"];
+        let directory = bsa
+            .get(&ArchiveKey::from(b"."))
+            .context("failed to get root directory from archive")?;
+        assert_eq!(directory.len(), files.len());
+
+        for file_name in files {
+            let path = root.join(file_name);
+            let metadata = fs::metadata(&path)
+                .with_context(|| format!("failed to get metadata for file: {path:?}"))?;
+            let file = directory
+                .get(&DirectoryKey::from(file_name))
+                .with_context(|| format!("failed to get file from directory: {file_name}"))?;
+            assert!(!file.is_compressed());
+            assert_eq!(file.len() as u64, metadata.len());
+        }
+
+        Ok(())
+    }
+
+    #[test]
+    fn flag_combinations() -> anyhow::Result<()> {
+        let infos = {
+            struct Pair {
+                hash: u64,
+                name: &'static str,
+            }
+
+            struct Info {
+                directory: Pair,
+                file: Pair,
+            }
+
+            impl Info {
+                fn new(
+                    directory_hash: u64,
+                    directory_name: &'static str,
+                    file_hash: u64,
+                    file_name: &'static str,
+                ) -> Self {
+                    Self {
+                        directory: Pair {
+                            hash: directory_hash,
+                            name: directory_name,
+                        },
+                        file: Pair {
+                            hash: file_hash,
+                            name: file_name,
+                        },
+                    }
+                }
+            }
+
+            [
+                Info::new(
+                    0x006819F973057265,
+                    "Share",
+                    0xDC415D456C077365,
+                    "License.txt",
+                ),
+                Info::new(
+                    0x00691A4374056573,
+                    "Tiles",
+                    0xDDE285B874093030,
+                    "tile_0000.png",
+                ),
+                Info::new(
+                    0x0E09AFBA620A6E64,
+                    "Background",
+                    0xC41A947762116F6D,
+                    "background_bottom.png",
+                ),
+                Info::new(
+                    0x4ADF420B74076170,
+                    "Tilemap",
+                    0x0D9BA627630A7273,
+                    "characters.png",
+                ),
+                Info::new(
+                    0x6A326CD4630B2033,
+                    "Construct 3",
+                    0xC7EDDCEA72066D65,
+                    "Readme.txt",
+                ),
+                Info::new(
+                    0x79CD3FEC630A7273,
+                    "Characters",
+                    0xD0E4FC14630E3030,
+                    "character_0000.png",
+                ),
+            ]
+        };
+
+        let mappings: Vec<_> = infos
+            .iter()
+            .map(|info| {
+                let path: PathBuf = [
+                    "data/tes4_flags_test",
+                    "data",
+                    info.directory.name,
+                    info.file.name,
+                ]
+                .into_iter()
+                .collect();
+                let fd = fs::File::open(&path)
+                    .with_context(|| format!("failed to open file: {path:?}"))?;
+                let map = unsafe { Mmap::map(&fd) }
+                    .with_context(|| format!("failed to memory map file: {path:?}"))?;
+                Ok(map)
+            })
+            .collect::<anyhow::Result<_>>()?;
+        let main: Archive = infos
+            .iter()
+            .zip(&mappings)
+            .map(|(info, mapping)| {
+                let file = File::from_decompressed(&mapping[..]);
+                let directory: Directory = [(info.file.name.into(), file)].into_iter().collect();
+                (info.directory.name.into(), directory)
+            })
+            .collect();
+
+        let test = |version: Version, flags: ArchiveFlags| -> anyhow::Result<()> {
+            let buffer = {
+                let mut v = Vec::new();
+                let options = ArchiveOptions::builder()
+                    .version(version)
+                    .flags(flags)
+                    .build();
+                main.write(&mut v, &options)
+                    .context("failed to write archive to buffer")?;
+                v
+            };
+
+            let (child, options) =
+                Archive::read(Borrowed(&buffer)).context("failed to read archive from buffer")?;
+            assert_eq!(options.version(), version);
+            assert_eq!(options.flags(), flags);
+            assert_eq!(main.len(), child.len());
+
+            let embedded_file_names = version != Version::v103 && flags.embedded_file_names();
+
+            for (info, mapping) in infos.iter().zip(&mappings) {
+                let archive_key: ArchiveKey = info.directory.name.into();
+                let directory = child
+                    .get_key_value(&archive_key)
+                    .with_context(|| format!("failed to get directory: {}", info.directory.name))?;
+                assert_eq!(directory.0.hash().numeric(), info.directory.hash);
+                assert_eq!(directory.1.len(), 1);
+                if flags.directory_strings() || embedded_file_names {
+                    assert_eq!(directory.0.name(), archive_key.name());
+                }
+
+                let directory_key: DirectoryKey = info.file.name.into();
+                let file = directory
+                    .1
+                    .get_key_value(&directory_key)
+                    .with_context(|| format!("failed to get file: {}", info.file.name))?;
+                assert_eq!(file.0.hash().numeric(), info.file.hash);
+                if flags.file_strings() || embedded_file_names {
+                    assert_eq!(file.0.name(), directory_key.name());
+                }
+
+                let decompressed_file = if file.1.is_compressed() {
+                    let options = FileCompressionOptions::builder().version(version).build();
+                    let result = file.1.decompress(&options).with_context(|| {
+                        format!("failed to decompress file: {}", info.file.name)
+                    })?;
+                    Some(result)
+                } else {
+                    None
+                };
+                let decompressed_bytes = decompressed_file.as_ref().unwrap_or(file.1).as_bytes();
+                assert_eq!(decompressed_bytes, &mapping[..]);
+            }
+
+            Ok(())
+        };
+
+        let versions = [Version::v103, Version::v104, Version::v105];
+        let flags = [
+            ArchiveFlags::DIRECTORY_STRINGS,
+            ArchiveFlags::FILE_STRINGS,
+            ArchiveFlags::COMPRESSED,
+            ArchiveFlags::XBOX_ARCHIVE,
+            ArchiveFlags::EMBEDDED_FILE_NAMES,
+        ];
+
+        for version in versions {
+            for i in 0..flags.len() {
+                for j in i..flags.len() {
+                    let f = flags[i..=j]
+                        .iter()
+                        .copied()
+                        .reduce(|acc, x| acc.union(x))
+                        .unwrap();
+                    test(version, f).with_context(|| {
+                        format!("archive test failed for version ({version:?}) with flags ({f:?})")
+                    })?;
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    #[test]
+    fn invalid_magic() -> anyhow::Result<()> {
+        let path = Path::new("data/tes4_invalid_test/invalid_magic.bsa");
+        match Archive::read(path) {
+            Err(Error::InvalidMagic(0x00324142)) => Ok(()),
+            Err(err) => Err(err.into()),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_size() -> anyhow::Result<()> {
+        let path = Path::new("data/tes4_invalid_test/invalid_size.bsa");
+        match Archive::read(path) {
+            Err(Error::InvalidHeaderSize(0xCC)) => Ok(()),
+            Err(err) => Err(err.into()),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_version() -> anyhow::Result<()> {
+        let path = Path::new("data/tes4_invalid_test/invalid_version.bsa");
+        match Archive::read(path) {
+            Err(Error::InvalidVersion(42)) => Ok(()),
+            Err(err) => Err(anyhow::Error::from(err)),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn invalid_exhausted() -> anyhow::Result<()> {
+        let path = Path::new("data/tes4_invalid_test/invalid_exhausted.bsa");
+        match Archive::read(path) {
+            Err(Error::Io(error)) => {
+                assert_eq!(error.kind(), io::ErrorKind::UnexpectedEof);
+                Ok(())
+            }
+            Err(err) => Err(err.into()),
+            Ok(_) => anyhow::bail!("read should have failed"),
+        }
+    }
+
+    #[test]
+    fn data_sharing_name() -> anyhow::Result<()> {
+        let path = Path::new("data/tes4_data_sharing_name_test/share.bsa");
+        let (archive, options) = Archive::read(path).context("failed to read archive")?;
+        assert_eq!(options.version, Version::TES5);
+        assert!(options.flags.embedded_file_names());
+
+        let find = |directory_name: &str, file_name: &str| -> anyhow::Result<()> {
+            let directory = archive
+                .get_key_value(&ArchiveKey::from(directory_name))
+                .with_context(|| format!("failed to get directory: {directory_name}"))?;
+            assert_eq!(directory.0.name(), directory_name);
+
+            let file = directory
+                .1
+                .get_key_value(&DirectoryKey::from(file_name))
+                .with_context(|| format!("failed to get file: {file_name}"))?;
+            assert_eq!(file.0.name(), file_name);
+
+            Ok(())
+        };
+
+        find("misc1", "example1.txt")?;
+        find("misc2", "example2.txt")?;
+
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes4/directory.rs.html b/src/ba2/tes4/directory.rs.html new file mode 100644 index 0000000..6551111 --- /dev/null +++ b/src/ba2/tes4/directory.rs.html @@ -0,0 +1,65 @@ +directory.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+
use crate::{
+    derive,
+    tes4::{self, File, FileHash},
+};
+use bstr::BString;
+
+derive::key!(Key: FileHash);
+
+impl<'bytes> Key<'bytes> {
+    #[must_use]
+    fn hash_in_place(name: &mut BString) -> FileHash {
+        tes4::hash_file_in_place(name)
+    }
+}
+
+derive::mapping! {
+    /// Represents a directory within the TES4 virtual filesystem.
+    Directory
+    Map: (Key: FileHash) => File
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tes4::Directory;
+
+    #[test]
+    fn default_state() {
+        let d = Directory::new();
+        assert!(d.is_empty());
+        assert!(d.len() == 0);
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes4/file.rs.html b/src/ba2/tes4/file.rs.html new file mode 100644 index 0000000..4091373 --- /dev/null +++ b/src/ba2/tes4/file.rs.html @@ -0,0 +1,697 @@ +file.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+
use crate::{
+    containers::CompressableBytes,
+    derive,
+    io::Source,
+    tes4::{ArchiveOptions, CompressionCodec, Error, Result, Version},
+    CompressionResult,
+};
+use flate2::{
+    write::{ZlibDecoder, ZlibEncoder},
+    Compression,
+};
+use lzzzz::lz4f::{self, AutoFlush, PreferencesBuilder};
+use std::io::Write;
+
+/// See also [`FileCompressionOptions`](CompressionOptions).
+#[derive(Debug, Default)]
+#[repr(transparent)]
+pub struct CompressionOptionsBuilder(CompressionOptions);
+
+impl CompressionOptionsBuilder {
+    #[must_use]
+    pub fn build(self) -> CompressionOptions {
+        self.0
+    }
+
+    #[must_use]
+    pub fn compression_codec(mut self, compression_codec: CompressionCodec) -> Self {
+        self.0.compression_codec = compression_codec;
+        self
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    #[must_use]
+    pub fn version(mut self, version: Version) -> Self {
+        self.0.version = version;
+        self
+    }
+}
+
+impl From<ArchiveOptions> for CompressionOptionsBuilder {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for CompressionOptionsBuilder {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self(value.into())
+    }
+}
+
+/// Common parameters to configure how files are compressed/decompressed.
+///
+/// ```rust
+/// use ba2::tes4::{FileCompressionOptions, Version};
+///
+/// // Configure for TES:IV
+/// let _ = FileCompressionOptions::builder()
+///     .version(Version::TES4)
+///     .build();
+///
+/// // Configure for F3/FNV/TES:V
+/// let _ = FileCompressionOptions::builder()
+///     .version(Version::FO3)
+///     .build();
+///
+/// // Configure for SSE
+/// let _ = FileCompressionOptions::builder()
+///     .version(Version::SSE)
+///     .build();
+/// ```
+#[derive(Clone, Copy, Debug, Default)]
+pub struct CompressionOptions {
+    version: Version,
+    compression_codec: CompressionCodec,
+}
+
+impl CompressionOptions {
+    #[must_use]
+    pub fn builder() -> CompressionOptionsBuilder {
+        CompressionOptionsBuilder::new()
+    }
+
+    #[must_use]
+    pub fn compression_codec(&self) -> CompressionCodec {
+        self.compression_codec
+    }
+
+    #[must_use]
+    pub fn version(&self) -> Version {
+        self.version
+    }
+}
+
+impl From<ArchiveOptions> for CompressionOptions {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for CompressionOptions {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self {
+            version: value.version(),
+            ..Default::default()
+        }
+    }
+}
+
+/// See also [`FileReadOptions`](ReadOptions).
+#[derive(Debug, Default)]
+#[repr(transparent)]
+pub struct ReadOptionsBuilder(ReadOptions);
+
+impl ReadOptionsBuilder {
+    #[must_use]
+    pub fn build(self) -> ReadOptions {
+        self.0
+    }
+
+    #[must_use]
+    pub fn compression_codec(mut self, compression_codec: CompressionCodec) -> Self {
+        self.0.compression_options.compression_codec = compression_codec;
+        self
+    }
+
+    #[must_use]
+    pub fn compression_result(mut self, compression_result: CompressionResult) -> Self {
+        self.0.compression_result = compression_result;
+        self
+    }
+
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    #[must_use]
+    pub fn version(mut self, version: Version) -> Self {
+        self.0.compression_options.version = version;
+        self
+    }
+}
+
+impl From<ArchiveOptions> for ReadOptionsBuilder {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for ReadOptionsBuilder {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self(value.into())
+    }
+}
+
+/// Common parameters to configure how files are read.
+///
+/// ```rust
+/// use ba2::{
+///     tes4::{FileReadOptions, Version},
+///     CompressionResult,
+/// };
+///
+/// // Read and compress a file for TES:IV
+/// let _ = FileReadOptions::builder()
+///     .version(Version::TES4)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+///
+/// // Read and compress a file for F3/FNV/TES:V
+/// let _ = FileReadOptions::builder()
+///     .version(Version::FO3)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+///
+/// // Read and compress a file for SSE
+/// let _ = FileReadOptions::builder()
+///     .version(Version::SSE)
+///     .compression_result(CompressionResult::Compressed)
+///     .build();
+/// ```
+#[derive(Clone, Copy, Debug, Default)]
+pub struct ReadOptions {
+    compression_options: CompressionOptions,
+    compression_result: CompressionResult,
+}
+
+impl ReadOptions {
+    #[must_use]
+    pub fn builder() -> ReadOptionsBuilder {
+        ReadOptionsBuilder::new()
+    }
+
+    #[must_use]
+    pub fn compression_codec(&self) -> CompressionCodec {
+        self.compression_options.compression_codec
+    }
+
+    #[must_use]
+    pub fn compression_result(&self) -> CompressionResult {
+        self.compression_result
+    }
+
+    #[must_use]
+    pub fn version(&self) -> Version {
+        self.compression_options.version
+    }
+}
+
+impl From<ArchiveOptions> for ReadOptions {
+    fn from(value: ArchiveOptions) -> Self {
+        (&value).into()
+    }
+}
+
+impl From<&ArchiveOptions> for ReadOptions {
+    fn from(value: &ArchiveOptions) -> Self {
+        Self {
+            compression_options: value.into(),
+            ..Default::default()
+        }
+    }
+}
+
+/// Represents a file within the TES4 virtual filesystem.
+#[derive(Clone, Debug, Default)]
+pub struct File<'bytes> {
+    pub(crate) bytes: CompressableBytes<'bytes>,
+}
+
+type ReadResult<T> = T;
+derive::compressable_bytes!(File: CompressionOptions);
+derive::reader_with_options!((File: ReadOptions) => ReadResult);
+
+impl<'bytes> File<'bytes> {
+    pub fn compress_into(&self, out: &mut Vec<u8>, options: &CompressionOptions) -> Result<()> {
+        if self.is_compressed() {
+            Err(Error::AlreadyCompressed)
+        } else {
+            match options.version {
+                Version::v103 => self.compress_into_zlib(out),
+                Version::v104 => match options.compression_codec {
+                    CompressionCodec::Normal => self.compress_into_zlib(out),
+                },
+                Version::v105 => self.compress_into_lz4(out),
+            }
+        }
+    }
+
+    pub fn decompress_into(&self, out: &mut Vec<u8>, options: &CompressionOptions) -> Result<()> {
+        let Some(decompressed_len) = self.decompressed_len() else {
+            return Err(Error::AlreadyDecompressed);
+        };
+
+        out.reserve_exact(decompressed_len);
+        let out_len = match options.version {
+            Version::v103 => self.decompress_into_zlib(out),
+            Version::v104 => match options.compression_codec {
+                CompressionCodec::Normal => self.decompress_into_zlib(out),
+            },
+            Version::v105 => self.decompress_into_lz4(out),
+        }?;
+
+        if out_len == decompressed_len {
+            Ok(())
+        } else {
+            Err(Error::DecompressionSizeMismatch {
+                expected: decompressed_len,
+                actual: out_len,
+            })
+        }
+    }
+
+    #[allow(clippy::unused_self)]
+    fn copy_with<'other>(&self, bytes: CompressableBytes<'other>) -> File<'other> {
+        File { bytes }
+    }
+
+    fn compress_into_lz4(&self, out: &mut Vec<u8>) -> Result<()> {
+        let prefs = PreferencesBuilder::new()
+            .compression_level(9)
+            .auto_flush(AutoFlush::Enabled)
+            .build();
+        lz4f::compress_to_vec(self.as_bytes(), out, &prefs)?;
+        Ok(())
+    }
+
+    fn compress_into_zlib(&self, out: &mut Vec<u8>) -> Result<()> {
+        let mut e = ZlibEncoder::new(out, Compression::default());
+        e.write_all(self.as_bytes())?;
+        e.finish()?;
+        Ok(())
+    }
+
+    fn decompress_into_lz4(&self, out: &mut Vec<u8>) -> Result<usize> {
+        let len = lz4f::decompress_to_vec(self.as_bytes(), out)?;
+        Ok(len)
+    }
+
+    fn decompress_into_zlib(&self, out: &mut Vec<u8>) -> Result<usize> {
+        let mut d = ZlibDecoder::new(out);
+        d.write_all(self.as_bytes())?;
+        Ok(d.total_out().try_into()?)
+    }
+
+    #[allow(clippy::trivially_copy_pass_by_ref)]
+    fn do_read<In>(stream: &mut In, options: &ReadOptions) -> Result<ReadResult<Self>>
+    where
+        In: ?Sized + Source<'bytes>,
+    {
+        let decompressed = Self {
+            bytes: stream.read_bytes_to_end().into_compressable(None),
+        };
+        match options.compression_result {
+            CompressionResult::Decompressed => Ok(decompressed),
+            CompressionResult::Compressed => decompressed.compress(&options.compression_options),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{prelude::*, tes4::File};
+
+    #[test]
+    fn default_state() {
+        let f = File::new();
+        assert!(!f.is_compressed());
+        assert!(f.is_empty());
+        assert_eq!(f.len(), 0);
+        assert_eq!(f.as_bytes().len(), 0);
+    }
+
+    #[test]
+    fn assign_state() {
+        let payload = [0u8; 64];
+        let f = File::from_decompressed(&payload[..]);
+        assert_eq!(f.len(), payload.len());
+        assert_eq!(f.as_ptr(), payload.as_ptr());
+        assert_eq!(f.as_bytes().len(), payload.len());
+        assert_eq!(f.as_bytes().as_ptr(), payload.as_ptr());
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes4/hashing.rs.html b/src/ba2/tes4/hashing.rs.html new file mode 100644 index 0000000..5b30cf0 --- /dev/null +++ b/src/ba2/tes4/hashing.rs.html @@ -0,0 +1,505 @@ +hashing.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+
use crate::{cc, derive, hashing};
+use bstr::{BStr, BString, ByteSlice as _};
+use core::cmp::Ordering;
+
+/// The underlying hash object used to uniquely identify objects within the archive.
+#[derive(Clone, Copy, Debug, Default)]
+#[repr(C)]
+pub struct Hash {
+    /// The last character of the path (directory) or stem (file).
+    pub last: u8,
+    /// The second to last character of the path (directory) or stem (file).
+    pub last2: u8,
+    /// The length of the path (directory) or stem (file).
+    pub length: u8,
+    /// The first character of the path (directory) or stem (file).
+    pub first: u8,
+    pub crc: u32,
+}
+
+derive::hash!(DirectoryHash);
+derive::hash!(FileHash);
+
+impl Hash {
+    #[must_use]
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    #[allow(clippy::identity_op, clippy::erasing_op)]
+    #[must_use]
+    pub fn numeric(&self) -> u64 {
+        (u64::from(self.last) << (0 * 8))
+            | (u64::from(self.last2) << (1 * 8))
+            | (u64::from(self.length) << (2 * 8))
+            | (u64::from(self.first) << (3 * 8))
+            | (u64::from(self.crc) << (4 * 8))
+    }
+}
+
+impl PartialEq for Hash {
+    fn eq(&self, other: &Self) -> bool {
+        self.numeric() == other.numeric()
+    }
+}
+
+impl Eq for Hash {}
+
+impl PartialOrd for Hash {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Hash {
+    fn cmp(&self, other: &Self) -> Ordering {
+        self.numeric().cmp(&other.numeric())
+    }
+}
+
+fn crc32(bytes: &[u8]) -> u32 {
+    let mut crc: u32 = 0;
+    for &b in bytes {
+        crc = u32::from(b).wrapping_add(crc.wrapping_mul(0x1003F));
+    }
+    crc
+}
+
+/// Produces a hash using the given path.
+#[must_use]
+pub fn hash_directory(path: &BStr) -> (DirectoryHash, BString) {
+    let mut path = path.to_owned();
+    (hash_directory_in_place(&mut path), path)
+}
+
+/// Produces a hash using the given path.
+///
+/// The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.
+#[must_use]
+pub fn hash_directory_in_place(path: &mut BString) -> DirectoryHash {
+    hashing::normalize_path(path);
+    let mut h = Hash::new();
+    let len = path.len();
+    if len >= 3 {
+        h.last2 = path[len - 2];
+    }
+    if len >= 1 {
+        h.last = path[len - 1];
+        h.first = path[0];
+    }
+
+    // truncation here is intentional, this is how bethesda does it
+    #[allow(clippy::cast_possible_truncation)]
+    {
+        h.length = len as u8;
+    }
+
+    if h.length > 3 {
+        // skip first and last two chars -> already processed
+        h.crc = crc32(&path[1..len - 2]);
+    }
+
+    h.into()
+}
+
+/// Produces a hash using the given path.
+#[must_use]
+pub fn hash_file(path: &BStr) -> (FileHash, BString) {
+    let mut path = path.to_owned();
+    (hash_file_in_place(&mut path), path)
+}
+
+/// Produces a hash using the given path.
+///
+/// The path is normalized in place. After the function returns, the path contains the string that would be stored on disk.
+#[must_use]
+pub fn hash_file_in_place(path: &mut BString) -> FileHash {
+    const LUT: [u32; 6] = [
+        cc::make_four(b""),
+        cc::make_four(b".nif"),
+        cc::make_four(b".kf"),
+        cc::make_four(b".dds"),
+        cc::make_four(b".wav"),
+        cc::make_four(b".adp"),
+    ];
+
+    hashing::normalize_path(path);
+    if let Some(pos) = path.iter().rposition(|&x| x == b'\\') {
+        path.drain(..=pos);
+    }
+
+    let path: &_ = path;
+    let (stem, extension) = if let Some(split_at) = path.iter().rposition(|&x| x == b'.') {
+        (&path[..split_at], &path[split_at..])
+    } else {
+        (&path[..], b"".as_slice())
+    };
+
+    if !stem.is_empty() && stem.len() < 260 && extension.len() < 16 {
+        let mut h: Hash = hash_directory(stem.as_bstr()).0.into();
+        h.crc = u32::wrapping_add(h.crc, crc32(extension));
+
+        let cc = cc::make_four(extension);
+        // truncations are on purpose
+        #[allow(clippy::cast_possible_truncation)]
+        if let Some(i) = LUT.iter().position(|&x| x == cc) {
+            let i = i as u8;
+            h.first = u32::from(h.first).wrapping_add(32 * u32::from(i & 0xFC)) as u8;
+            h.last = u32::from(h.last).wrapping_add(u32::from(i & 0xFE) << 6) as u8;
+            h.last2 = u32::from(h.last2).wrapping_add(u32::from(i.wrapping_shl(7))) as u8;
+        }
+
+        h.into()
+    } else {
+        FileHash::default()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tes4;
+    use bstr::ByteSlice as _;
+
+    #[test]
+    fn validate_directory_hashes() {
+        let h = |path: &[u8]| tes4::hash_directory(path.as_bstr()).0.numeric();
+        assert_eq!(
+            h(b"textures/armor/amuletsandrings/elder council"),
+            0x04BC422C742C696C
+        );
+        assert_eq!(
+            h(b"sound/voice/skyrim.esm/maleuniquedbguardian"),
+            0x594085AC732B616E
+        );
+        assert_eq!(h(b"textures/architecture/windhelm"), 0xC1D97EBE741E6C6D);
+    }
+
+    #[test]
+    fn validate_file_hashes() {
+        let h = |path: &[u8]| tes4::hash_file(path.as_bstr()).0.numeric();
+        assert_eq!(h(b"darkbrotherhood__0007469a_1.fuz"), 0x011F11B0641B5F31);
+        assert_eq!(h(b"elder_council_amulet_n.dds"), 0xDC531E2F6516DFEE);
+        assert_eq!(
+            h(b"testtoddquest_testtoddhappy_00027fa2_1.mp3"),
+            0xDE0301EE74265F31
+        );
+        assert_eq!(h(b"Mar\xEDa_F.fuz"), 0x690E07826D075F66);
+    }
+
+    #[test]
+    fn empty_path_equivalent_to_current_path() {
+        let empty = tes4::hash_directory(b"".as_bstr());
+        let current = tes4::hash_directory(b".".as_bstr());
+        assert_eq!(empty, current);
+    }
+
+    #[test]
+    fn archive_tool_detects_file_extensions_incorrectly() {
+        let gitignore = tes4::hash_file(b".gitignore".as_bstr()).0;
+        let gitmodules = tes4::hash_file(b".gitmodules".as_bstr()).0;
+        assert_eq!(gitignore, gitmodules);
+        assert_eq!(gitignore.first, b'\0');
+        assert_eq!(gitignore.last2, b'\0');
+        assert_eq!(gitignore.last, b'\0');
+        assert_eq!(gitignore.length, 0);
+        assert_eq!(gitignore.crc, 0);
+        assert_eq!(gitignore.numeric(), 0);
+    }
+
+    #[test]
+    fn root_paths_are_included_in_hashes() {
+        let h1 = tes4::hash_directory(b"C:\\foo\\bar\\baz".as_bstr()).0;
+        let h2 = tes4::hash_directory(b"foo/bar/baz".as_bstr()).0;
+        assert_ne!(h1, h2);
+    }
+
+    #[test]
+    fn directories_longer_than_259_chars_are_equivalent_to_empty_path() {
+        let long = tes4::hash_directory([0u8; 260].as_bstr()).0;
+        let empty = tes4::hash_directory(b"".as_bstr()).0;
+        assert_eq!(long, empty);
+    }
+
+    #[test]
+    fn files_longer_than_259_chars_will_fail() {
+        let good = tes4::hash_file([0u8; 259].as_bstr()).0;
+        let bad = tes4::hash_file([0u8; 260].as_bstr()).0;
+        assert_ne!(good.numeric(), 0);
+        assert_eq!(bad.numeric(), 0)
+    }
+
+    #[test]
+    fn file_extensions_longer_than_14_chars_will_fail() {
+        let good = tes4::hash_file(b"test.123456789ABCDE".as_bstr()).0;
+        let bad = tes4::hash_file(b"test.123456789ABCDEF".as_bstr()).0;
+        assert_ne!(good.numeric(), 0);
+        assert_eq!(bad.numeric(), 0);
+    }
+
+    #[test]
+    fn root_paths_are_included_in_directory_names() {
+        let h1 = tes4::hash_directory(b"C:\\foo\\bar\\baz".as_bstr()).0;
+        let h2 = tes4::hash_directory(b"foo\\bar\\baz".as_bstr()).0;
+        assert_ne!(h1, h2);
+    }
+
+    #[test]
+    fn parent_directories_are_not_included_in_file_names() {
+        let h1 = tes4::hash_file(b"users/john/test.txt".as_bstr()).0;
+        let h2 = tes4::hash_file(b"test.txt".as_bstr()).0;
+        assert_eq!(h1, h2);
+    }
+}
+
\ No newline at end of file diff --git a/src/ba2/tes4/mod.rs.html b/src/ba2/tes4/mod.rs.html new file mode 100644 index 0000000..e4e3125 --- /dev/null +++ b/src/ba2/tes4/mod.rs.html @@ -0,0 +1,341 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+
#![doc(alias = "oblivion")]
+#![doc(alias = "fallout 3")]
+#![doc(alias = "fo3")]
+#![doc(alias = "fallout new vegas")]
+#![doc(alias = "new vegas")]
+#![doc(alias = "fnv")]
+#![doc(alias = "tes5")]
+#![doc(alias = "skyrim")]
+#![doc(alias = "sse")]
+#![doc(alias = "special edition")]
+
+//! TES IV: Oblivion
+//!
+//! *"You ... I've seen you... Let me see your face... You are the one from my dreams... Then the stars were right, and this is the day. Gods give me strength."*
+//!
+//! This format debuted with Oblivion and sunset with Skyrim: SSE. This is the first format to introduce compression, and primarily utilizes zlib/lz4 for this purpose. Unlike other formats, [`tes4`](crate::tes4) utilizes a split architecture where files and directories are tracked as separate paths, rather than combined.
+//!
+//! # Reading
+//! ```rust
+//! use ba2::{
+//!     prelude::*,
+//!     tes4::{Archive, ArchiveKey, DirectoryKey, FileCompressionOptions},
+//! };
+//! use std::{fs, path::Path};
+//!
+//! fn example() -> Option<()> {
+//!     let path = Path::new("path/to/oblivion/Data/Oblivion - Voices2.bsa");
+//!     let (archive, meta) = Archive::read(path).ok()?;
+//!     let file = archive
+//!         .get(&ArchiveKey::from(b"sound/voice/oblivion.esm/imperial/m"))?
+//!         .get(&DirectoryKey::from(
+//!             b"testtoddquest_testtoddhappy_00027fa2_1.mp3",
+//!         ))?;
+//!     let mut dst = fs::File::create("happy.mp3").ok()?;
+//!     let options: FileCompressionOptions = meta.into();
+//!     file.write(&mut dst, &options).ok()?;
+//!     Some(())
+//! }
+//! ```
+//!
+//! # Writing
+//! ```rust
+//! use ba2::{
+//!     prelude::*,
+//!     tes4::{
+//!         Archive, ArchiveKey, ArchiveOptions, ArchiveTypes, Directory, DirectoryKey, File, Version,
+//!     },
+//! };
+//! use std::fs;
+//!
+//! fn example() -> Option<()> {
+//!     let file = File::from_decompressed(b"Hello world!\n");
+//!     let directory: Directory = [(DirectoryKey::from(b"hello.txt"), file)]
+//!         .into_iter()
+//!         .collect();
+//!     let archive: Archive = [(ArchiveKey::from(b"misc"), directory)]
+//!         .into_iter()
+//!         .collect();
+//!     let mut dst = fs::File::create("example.bsa").ok()?;
+//!     let options = ArchiveOptions::builder()
+//!         .types(ArchiveTypes::MISC)
+//!         .version(Version::SSE)
+//!         .build();
+//!     archive.write(&mut dst, &options).ok()?;
+//!     Some(())
+//! }
+//! ```
+
+mod archive;
+mod directory;
+mod file;
+mod hashing;
+
+pub use self::{
+    archive::{
+        Archive, Flags as ArchiveFlags, Key as ArchiveKey, Options as ArchiveOptions,
+        OptionsBuilder as ArchiveOptionsBuilder, Types as ArchiveTypes,
+    },
+    directory::{Directory, Key as DirectoryKey},
+    file::{
+        CompressionOptions as FileCompressionOptions,
+        CompressionOptionsBuilder as FileCompressionOptionsBuilder, File,
+        ReadOptions as FileReadOptions, ReadOptionsBuilder as FileReadOptionsBuilder,
+    },
+    hashing::{
+        hash_directory, hash_directory_in_place, hash_file, hash_file_in_place, DirectoryHash,
+        FileHash, Hash,
+    },
+};
+
+use core::num::TryFromIntError;
+use lzzzz::lz4f;
+use std::io;
+
+#[non_exhaustive]
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+    #[error("can not compress the given file because it is already compressed")]
+    AlreadyCompressed,
+
+    #[error("can not decompress the given file because it is already decompressed")]
+    AlreadyDecompressed,
+
+    #[error("buffer failed to decompress to the expected size... expected {expected} bytes, but got {actual} bytes")]
+    DecompressionSizeMismatch { expected: usize, actual: usize },
+
+    #[error("an operation on two integers would have overflowed and corrupted data")]
+    IntegralOverflow,
+
+    #[error("an operation on an integer would have truncated and corrupted data")]
+    IntegralTruncation,
+
+    #[error("invalid size read from archive header: {0}")]
+    InvalidHeaderSize(u32),
+
+    #[error("invalid magic read from archive header: {0}")]
+    InvalidMagic(u32),
+
+    #[error("invalid version read from archive header: {0}")]
+    InvalidVersion(u32),
+
+    #[error(transparent)]
+    Io(#[from] io::Error),
+
+    #[error(transparent)]
+    LZ4(#[from] lz4f::Error),
+}
+
+impl From<TryFromIntError> for Error {
+    fn from(_: TryFromIntError) -> Self {
+        Self::IntegralTruncation
+    }
+}
+
+pub type Result<T> = core::result::Result<T, Error>;
+
+/// Specifies the codec to use when performing compression/decompression actions on files.
+#[non_exhaustive]
+#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
+pub enum CompressionCodec {
+    /// The default compression codec.
+    #[default]
+    Normal,
+    //XMem,
+}
+
+/// The archive version.
+///
+/// Each version has an impact on the abi of the TES4 archive file format.
+#[allow(non_camel_case_types)]
+#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
+pub enum Version {
+    #[default]
+    v103 = 103,
+    v104 = 104,
+    v105 = 105,
+}
+
+impl Version {
+    /// The Elder Scrolls IV: Oblivion.
+    pub const TES4: Self = Self::v103;
+    /// Fallout 3.
+    pub const FO3: Self = Self::v104;
+    /// Fallout: New Vegas.
+    pub const FNV: Self = Self::v104;
+    /// The Elder Scrolls V: Skyrim.
+    pub const TES5: Self = Self::v104;
+    /// The Elder Scrolls V: Skyrim - Special Edition.
+    pub const SSE: Self = Self::v105;
+}
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 0000000..1447df7 --- /dev/null +++ b/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 0000000..d7e9c14 --- /dev/null +++ b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 0000000..7a1e5fc Binary files /dev/null and b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 0000000..e766e06 Binary files /dev/null and b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 0000000..31aa793 --- /dev/null +++ b/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 0000000..1866ad4 Binary files /dev/null and b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 0000000..4b3edc2 --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 0000000..462c34e Binary files /dev/null and b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 0000000..0d2941e --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 0000000..10b558e Binary files /dev/null and b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 0000000..5ec64ee Binary files /dev/null and b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 0000000..181a07f Binary files /dev/null and b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 0000000..2ae08a7 Binary files /dev/null and b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md new file mode 100644 index 0000000..175fa4f --- /dev/null +++ b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md @@ -0,0 +1,98 @@ + + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 0000000..0263fc3 Binary files /dev/null and b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/static.files/clipboard-7571035ce49a181d.svg b/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 0000000..8adbd99 --- /dev/null +++ b/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/static.files/favicon-16x16-8b506e7a72182f1c.png b/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 0000000..ea4b45c Binary files /dev/null and b/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 0000000..8b34b51 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 0000000..69b8613 Binary files /dev/null and b/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/static.files/main-9dd44ab47b99a0fb.js b/static.files/main-9dd44ab47b99a0fb.js new file mode 100644 index 0000000..cfb9a38 --- /dev/null +++ b/static.files/main-9dd44ab47b99a0fb.js @@ -0,0 +1,12 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.body,"crate")){mobileTitle.innerText=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}})}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.body,"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(link.href===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}window.register_type_impls=imp=>{if(!imp||!imp[window.currentCrate]){return}window.pending_type_impls=null;const idMap=new Map();let implementations=document.getElementById("implementations-list");let trait_implementations=document.getElementById("trait-implementations-list");let trait_implementations_header=document.getElementById("trait-implementations");const script=document.querySelector("script[data-self-path]");const selfPath=script?script.getAttribute("data-self-path"):null;const mainContent=document.querySelector("#main-content");const sidebarSection=document.querySelector(".sidebar section");let methods=document.querySelector(".sidebar .block.method");let associatedTypes=document.querySelector(".sidebar .block.associatedtype");let associatedConstants=document.querySelector(".sidebar .block.associatedconstant");let sidebarTraitList=document.querySelector(".sidebar .block.trait-implementation");for(const impList of imp[window.currentCrate]){const types=impList.slice(2);const text=impList[0];const isTrait=impList[1]!==0;const traitName=impList[1];if(types.indexOf(selfPath)===-1){continue}let outputList=isTrait?trait_implementations:implementations;if(outputList===null){const outputListName=isTrait?"Trait Implementations":"Implementations";const outputListId=isTrait?"trait-implementations-list":"implementations-list";const outputListHeaderId=isTrait?"trait-implementations":"implementations";const outputListHeader=document.createElement("h2");outputListHeader.id=outputListHeaderId;outputListHeader.innerText=outputListName;outputList=document.createElement("div");outputList.id=outputListId;if(isTrait){const link=document.createElement("a");link.href=`#${outputListHeaderId}`;link.innerText="Trait Implementations";const h=document.createElement("h3");h.appendChild(link);trait_implementations=outputList;trait_implementations_header=outputListHeader;sidebarSection.appendChild(h);sidebarTraitList=document.createElement("ul");sidebarTraitList.className="block trait-implementation";sidebarSection.appendChild(sidebarTraitList);mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}else{implementations=outputList;if(trait_implementations){mainContent.insertBefore(outputListHeader,trait_implementations_header);mainContent.insertBefore(outputList,trait_implementations_header)}else{const mainContent=document.querySelector("#main-content");mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}}}const template=document.createElement("template");template.innerHTML=text;onEachLazy(template.content.querySelectorAll("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});onEachLazy(template.content.querySelectorAll("[id]"),el=>{let i=0;if(idMap.has(el.id)){i=idMap.get(el.id)}else if(document.getElementById(el.id)){i=1;while(document.getElementById(`${el.id}-${2 * i}`)){i=2*i}while(document.getElementById(`${el.id}-${i}`)){i+=1}}if(i!==0){const oldHref=`#${el.id}`;const newHref=`#${el.id}-${i}`;el.id=`${el.id}-${i}`;onEachLazy(template.content.querySelectorAll("a[href]"),link=>{if(link.getAttribute("href")===oldHref){link.href=newHref}})}idMap.set(el.id,i+1)});const templateAssocItems=template.content.querySelectorAll("section.tymethod, "+"section.method, section.associatedtype, section.associatedconstant");if(isTrait){const li=document.createElement("li");const a=document.createElement("a");a.href=`#${template.content.querySelector(".impl").id}`;a.textContent=traitName;li.appendChild(a);sidebarTraitList.append(li)}else{onEachLazy(templateAssocItems,item=>{let block=hasClass(item,"associatedtype")?associatedTypes:(hasClass(item,"associatedconstant")?associatedConstants:(methods));if(!block){const blockTitle=hasClass(item,"associatedtype")?"Associated Types":(hasClass(item,"associatedconstant")?"Associated Constants":("Methods"));const blockClass=hasClass(item,"associatedtype")?"associatedtype":(hasClass(item,"associatedconstant")?"associatedconstant":("method"));const blockHeader=document.createElement("h3");const blockLink=document.createElement("a");blockLink.href="#implementations";blockLink.innerText=blockTitle;blockHeader.appendChild(blockLink);block=document.createElement("ul");block.className=`block ${blockClass}`;const insertionReference=methods||sidebarTraitList;if(insertionReference){const insertionReferenceH=insertionReference.previousElementSibling;sidebarSection.insertBefore(blockHeader,insertionReferenceH);sidebarSection.insertBefore(block,insertionReferenceH)}else{sidebarSection.appendChild(blockHeader);sidebarSection.appendChild(block)}if(hasClass(item,"associatedtype")){associatedTypes=block}else if(hasClass(item,"associatedconstant")){associatedConstants=block}else{methods=block}}const li=document.createElement("li");const a=document.createElement("a");a.innerText=item.id.split("-")[0].split(".")[1];a.href=`#${item.id}`;li.appendChild(a);block.appendChild(li)})}outputList.appendChild(template.content)}for(const list of[methods,associatedTypes,associatedConstants,sidebarTraitList]){if(!list){continue}const newChildren=Array.prototype.slice.call(list.children);newChildren.sort((a,b)=>{const aI=a.innerText;const bI=b.innerText;return aIbI?1:0});list.replaceChildren(...newChildren)}};if(window.pending_type_impls){window.register_type_impls(window.pending_type_impls)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,e)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 0000000..469959f --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/static.files/noscript-5d8b3c7633ad77ba.css b/static.files/noscript-5d8b3c7633ad77ba.css new file mode 100644 index 0000000..8c63ef0 --- /dev/null +++ b/static.files/noscript-5d8b3c7633ad77ba.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}@media (prefers-color-scheme:dark){:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}} \ No newline at end of file diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 0000000..62424d8 --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-9ee3a5e31a2afa3e.css b/static.files/rustdoc-9ee3a5e31a2afa3e.css new file mode 100644 index 0000000..8749d0e --- /dev/null +++ b/static.files/rustdoc-9ee3a5e31a2afa3e.css @@ -0,0 +1,10 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.sub-logo-container,.logo-container{line-height:0;display:block;}.sub-logo-container{margin-right:32px;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;}.rustdoc.src .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;z-index:1;}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.src .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:300px;}.src-sidebar-expanded .src .sidebar>*:not(#src-sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.logo-container>img{height:48px;width:48px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>.version,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar .current a,.sidebar-crate a.logo-container:hover+h2 a,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.sidebar-crate{display:flex;align-items:center;justify-content:center;margin:14px 32px 1rem;row-gap:10px;column-gap:32px;flex-wrap:wrap;}.sidebar-crate h2{flex-grow:1;margin:0 -8px;align-self:start;}.sidebar-crate .logo-container{margin:0 -16px 0 -16px;text-align:center;}.sidebar-crate h2 a{display:block;margin:0 calc(-24px + 0.25rem) 0 -0.5rem;padding:calc((16px - 0.57rem ) / 2 ) 0.25rem;padding-left:0.5rem;}.sidebar-crate h2 .version{display:block;font-weight:normal;font-size:1rem;overflow-wrap:break-word;margin-top:calc((-16px + 0.57rem ) / 2 );}.sidebar-crate+.version{margin-top:-1rem;margin-bottom:1rem;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:2;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;align-items:center;vertical-align:text-bottom;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;vertical-align:baseline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}#src-sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#src-sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.src-sidebar-expanded #src-sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{max-width:100vw;width:100vw;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;margin-bottom:var(--nav-sub-mobile-padding);}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"]{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a,:root[data-theme="ayu"] #source-sidebar>.title{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img{filter:invert(100);} \ No newline at end of file diff --git a/static.files/scrape-examples-ef1e698c1d417c0c.js b/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 0000000..ba830e3 --- /dev/null +++ b/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/static.files/search-8fbf244ebcf71464.js b/static.files/search-8fbf244ebcf71464.js new file mode 100644 index 0000000..168023b --- /dev/null +++ b/static.files/search-8fbf244ebcf71464.js @@ -0,0 +1,5 @@ +"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias","generic",];const longItemTypes=["module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","primitive type","assoc type","constant","assoc const","union","foreign type","keyword","existential type","attribute macro","derive macro","trait alias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const TY_GENERIC=itemTypes.indexOf("generic");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;function buildTypeMapIndex(name){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){return typeNameIdMap.get(name)}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,id);return id}}function isWhitespace(c){return" \t\n\r".indexOf(c)!==-1}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return",>-]".indexOf(c)!==-1}function isStopCharacter(c){return isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","}function isPathSeparator(c){return c===":"||isWhitespace(c)}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(!isWhitespace(c)){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}return{name:"never",id:null,fullPath:["never"],pathWithoutLast:[],pathLast:"never",generics:[],typeFilter:"primitive",}}if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(path.includes("::::")){throw["Unexpected ","::::"]}else if(path.includes(" ::")){throw["Unexpected "," ::"]}else if(path.includes(":: ")){throw["Unexpected ",":: "]}const pathSegments=path.split(/::|\s+/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast:pathSegments[pathSegments.length-1],generics:generics,typeFilter,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",","," or ",endChar,...extra,", found ",c,]}throw["Expected ",",",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(isWhitespace(c)){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}}userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of result_list){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(result_list)}function checkGenerics(fnType,queryElem,whereClause,mgensInout){return unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgensInout,mgens=>{if(mgensInout){for(const[fid,qid]of mgens.entries()){mgensInout.set(fid,qid)}}return true})}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb){let mgens=new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;let fl=fnTypesIn.length;let fnTypes=fnTypesIn.slice();const backtracking=[];let i=0;let j=0;const backtrack=()=>{while(backtracking.length!==0){const{fnTypesScratch,mgensScratch,queryElemsOffset,fnTypesOffset,unbox,}=backtracking.pop();mgens=new Map(mgensScratch);const fnType=fnTypesScratch[fnTypesOffset];const queryElem=queryElems[queryElemsOffset];if(unbox){if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}mgens.set(fnType.id,0)}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;fnTypes=fnTypesScratch.toSpliced(fnTypesOffset,1,...generics);fl=fnTypes.length;i=queryElemsOffset-1}else{if(fnType.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}mgens.set(fnType.id,queryElem.id)}fnTypes=fnTypesScratch.slice();fl=fnTypes.length;const tmp=fnTypes[queryElemsOffset];fnTypes[queryElemsOffset]=fnTypes[fnTypesOffset];fnTypes[fnTypesOffset]=tmp;i=queryElemsOffset}return true}return false};for(i=0;i!==ql;++i){const queryElem=queryElems[i];const matchCandidates=[];let fnTypesScratch=null;let mgensScratch=null;for(j=i;j!==fl;++j){const fnType=fnTypes[j];if(unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}unifyFunctionTypes(fnType.generics,queryElem.generics,whereClause,mgens,mgensScratch=>{matchCandidates.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:false,});return false})}if(unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){if(!fnTypesScratch){fnTypesScratch=fnTypes.slice()}if(!mgensScratch){mgensScratch=new Map(mgens)}backtracking.push({fnTypesScratch,mgensScratch,queryElemsOffset:i,fnTypesOffset:j,unbox:true,})}}if(matchCandidates.length===0){if(backtrack()){continue}else{return false}}const{fnTypesOffset:candidate,mgensScratch:mgensNew}=matchCandidates.pop();if(fnTypes[candidate].id<0&&queryElems[i].id<0){mgens.set(fnTypes[candidate].id,queryElems[i].id)}for(const[fid,qid]of mgensNew){mgens.set(fid,qid)}const tmp=fnTypes[candidate];fnTypes[candidate]=fnTypes[i];fnTypes[i]=tmp;for(const otherCandidate of matchCandidates){backtracking.push(otherCandidate)}while(i===(ql-1)&&solutionCb&&!solutionCb(mgens)){if(!backtrack()){return false}}}return true}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgens.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(fnType.id!==queryElem.id){return false}if(fnType.generics.length===0&&queryElem.generics.length!==0){return false}const queryElemPathLength=queryElem.pathWithoutLast.length;if(queryElemPathLength>0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i=0){if(!whereClause){return false}if(mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause)}else if(fnType.generics&&fnType.generics.length>0){return checkIfInList(fnType.generics,queryElem,whereClause)}return false}function checkIfInList(list,elem,whereClause){for(const entry of list){if(checkType(entry,elem,whereClause)){return true}}return false}function checkType(row,elem,whereClause){if(row.id===null){return row.generics.length>0?checkIfInList(row.generics,elem,whereClause):false}if(row.id<0&&elem.id>=0){const gid=(-row.id)-1;return checkIfInList(whereClause[gid],elem,whereClause)}if(row.id<0&&elem.id<0){return true}const matchesExact=row.id===elem.id;const matchesArrayOrSlice=elem.id===typeNameIdOfArrayOrSlice&&(row.id===typeNameIdOfSlice||row.id===typeNameIdOfArray);if((matchesExact||matchesArrayOrSlice)&&typePassesFilter(elem.typeFilter,row.ty)){if(elem.generics.length>0){return checkGenerics(row,elem,whereClause,new Map())}return true}return checkIfInList(row.generics,elem,whereClause)}function checkPath(contains,ty,maxEditDistance){if(contains.length===0){return 0}let ret_dist=maxEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return maxEditDistance+1}for(let i=0;ilength){break}let dist_total=0;let aborted=false;for(let x=0;xmaxEditDistance){aborted=true;break}dist_total+=dist}if(!aborted){ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}}return ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,implDisambiguator:item.implDisambiguator,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){const inBounds=dist<=maxEditDistance||index!==-1;if(dist===0||(!parsedQuery.literalSearch&&inBounds)){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let index=-1,path_dist=0;const fullId=row.id;const searchWord=searchWords[pos];const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause);if(in_args){addIntoResults(results_in_args,fullId,pos,-1,0,0,maxEditDistance)}const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause);if(returned){addIntoResults(results_returned,fullId,pos,-1,0,0,maxEditDistance)}if(!typePassesFilter(elem.typeFilter,row.ty)){return}const row_index=row.normalizedName.indexOf(elem.pathLast);const word_index=searchWord.indexOf(elem.pathLast);if(row_index===-1){index=word_index}else if(word_index===-1){index=row_index}else if(word_index1){path_dist=checkPath(elem.pathWithoutLast,row,maxEditDistance);if(path_dist>maxEditDistance){return}}if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(searchWord,elem.pathLast,maxEditDistance);if(index===-1&&dist+path_dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens)})){return}addIntoResults(results,row.id,pos,0,0,0,Number.MAX_VALUE)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;let queryLen=0;for(const elem of parsedQuery.elems){queryLen+=elem.name.length}for(const elem of parsedQuery.returned){queryLen+=elem.name.length}const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem){if(typeNameIdMap.has(elem.pathLast)){elem.id=typeNameIdMap.get(elem.pathLast)}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.pathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}}for(const elem of parsedQuery.elems){convertNameToId(elem)}for(const elem of parsedQuery.returned){convertNameToId(elem)}if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||editDistance(name,key,maxEditDistance)<=maxEditDistance)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor=type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}if(item.implDisambiguator!==null){anchor=item.implDisambiguator+"/"+anchor}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html#"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";length+=1;const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+="

"+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.map(type=>buildItemSearchType(type,lowercasePaths))}function buildItemSearchType(type,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}if(pathIndex<0){return{id:pathIndex,ty:TY_GENERIC,path:null,generics,}}if(pathIndex===0){return{id:null,ty:null,path:null,generics,}}const item=lowercasePaths[pathIndex-1];return{id:buildTypeMapIndex(item.name),ty:item.ty,path:item.path,generics,}}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}lowercasePaths.push({ty:ty,name:name.toLowerCase(),path:path});paths[i]={ty:ty,name:name,path:path}}lastPath="";len=itemTypes.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),implDisambiguator:implDisambiguator.has(i)?implDisambiguator.get(i):null,};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})() \ No newline at end of file diff --git a/static.files/settings-74424d7eec62a23e.js b/static.files/settings-74424d7eec62a23e.js new file mode 100644 index 0000000..3014f75 --- /dev/null +++ b/static.files/settings-74424d7eec62a23e.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/static.files/src-script-3280b574d94e47b4.js b/static.files/src-script-3280b574d94e47b4.js new file mode 100644 index 0000000..9ea8892 --- /dev/null +++ b/static.files/src-script-3280b574d94e47b4.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth"){addClass(document.documentElement,"src-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"src-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="src-sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(srcIndex).forEach(key=>{srcIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(srcIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSrcLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSrcLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/static.files/storage-fec3eaa3851e447d.js b/static.files/storage-fec3eaa3851e447d.js new file mode 100644 index 0000000..a687118 --- /dev/null +++ b/static.files/storage-fec3eaa3851e447d.js @@ -0,0 +1 @@ +"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func,reversed){if(arr&&arr.length>0){if(reversed){for(let i=arr.length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0)}}) \ No newline at end of file diff --git a/static.files/wheel-7b819b6101059cd0.svg b/static.files/wheel-7b819b6101059cd0.svg new file mode 100644 index 0000000..83c07f6 --- /dev/null +++ b/static.files/wheel-7b819b6101059cd0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/trait.impl/ba2/trait.CompressableFrom.js b/trait.impl/ba2/trait.CompressableFrom.js new file mode 100644 index 0000000..5df944d --- /dev/null +++ b/trait.impl/ba2/trait.CompressableFrom.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/ba2/trait.Reader.js b/trait.impl/ba2/trait.Reader.js new file mode 100644 index 0000000..5df944d --- /dev/null +++ b/trait.impl/ba2/trait.Reader.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/ba2/trait.ReaderWithOptions.js b/trait.impl/ba2/trait.ReaderWithOptions.js new file mode 100644 index 0000000..5df944d --- /dev/null +++ b/trait.impl/ba2/trait.ReaderWithOptions.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/bitflags/traits/trait.Flags.js b/trait.impl/bitflags/traits/trait.Flags.js new file mode 100644 index 0000000..0dad800 --- /dev/null +++ b/trait.impl/bitflags/traits/trait.Flags.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Flags for Flags"],["impl Flags for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/bitflags/traits/trait.PublicFlags.js b/trait.impl/bitflags/traits/trait.PublicFlags.js new file mode 100644 index 0000000..eddefee --- /dev/null +++ b/trait.impl/bitflags/traits/trait.PublicFlags.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl PublicFlags for Flags"],["impl PublicFlags for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/bstr/ext_slice/trait.ByteSlice.js b/trait.impl/bstr/ext_slice/trait.ByteSlice.js new file mode 100644 index 0000000..5df944d --- /dev/null +++ b/trait.impl/bstr/ext_slice/trait.ByteSlice.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/bstr/ext_vec/trait.ByteVec.js b/trait.impl/bstr/ext_vec/trait.ByteVec.js new file mode 100644 index 0000000..5df944d --- /dev/null +++ b/trait.impl/bstr/ext_vec/trait.ByteVec.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/borrow/trait.Borrow.js b/trait.impl/core/borrow/trait.Borrow.js new file mode 100644 index 0000000..f379362 --- /dev/null +++ b/trait.impl/core/borrow/trait.Borrow.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Borrow<Hash> for FileHash"],["impl<'bytes> Borrow<FileHash> for Key<'bytes>"],["impl Borrow<Hash> for FileHash"],["impl<'bytes> Borrow<FileHash> for Key<'bytes>"],["impl<'bytes> Borrow<DirectoryHash> for Key<'bytes>"],["impl<'bytes> Borrow<FileHash> for Key<'bytes>"],["impl Borrow<Hash> for FileHash"],["impl Borrow<Hash> for DirectoryHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/borrow/trait.BorrowMut.js b/trait.impl/core/borrow/trait.BorrowMut.js new file mode 100644 index 0000000..fbb47b9 --- /dev/null +++ b/trait.impl/core/borrow/trait.BorrowMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl BorrowMut<Hash> for FileHash"],["impl BorrowMut<Hash> for FileHash"],["impl BorrowMut<Hash> for DirectoryHash"],["impl BorrowMut<Hash> for FileHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/clone/trait.Clone.js b/trait.impl/core/clone/trait.Clone.js new file mode 100644 index 0000000..291efd4 --- /dev/null +++ b/trait.impl/core/clone/trait.Clone.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes> Clone for Archive<'bytes>"],["impl Clone for Hash"],["impl Clone for ReadOptions"],["impl Clone for FileFormat"],["impl Clone for FileHash"],["impl Clone for CompressionFormat"],["impl Clone for Version"],["impl Clone for Hash"],["impl Clone for Types"],["impl<'bytes> Clone for Key<'bytes>"],["impl<'bytes> Clone for Archive<'bytes>"],["impl Clone for Flags"],["impl<'bytes> Clone for File<'bytes>"],["impl Clone for WriteOptions"],["impl Clone for ReadOptions"],["impl<'bytes> Clone for Archive<'bytes>"],["impl<'bytes> Clone for Directory<'bytes>"],["impl<'bytes> Clone for Key<'bytes>"],["impl<'bytes> Clone for Key<'bytes>"],["impl Clone for OptionsBuilder"],["impl Clone for Format"],["impl Clone for CompressionCodec"],["impl<'bytes> Clone for Chunk<'bytes>"],["impl<'bytes> Clone for Key<'bytes>"],["impl Clone for CompressionLevel"],["impl Clone for DX10"],["impl<'bytes> Clone for File<'bytes>"],["impl Clone for Options"],["impl Clone for Header"],["impl<'bytes> Clone for File<'bytes>"],["impl Clone for FileHash"],["impl Clone for CompressionOptions"],["impl Clone for CompressionOptions"],["impl Clone for Version"],["impl Clone for FileHash"],["impl Clone for Options"],["impl Clone for Hash"],["impl Clone for DirectoryHash"],["impl Clone for CompressionResult"],["impl Clone for GNMF"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Eq.js b/trait.impl/core/cmp/trait.Eq.js new file mode 100644 index 0000000..b23bf87 --- /dev/null +++ b/trait.impl/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Eq for Header"],["impl<'bytes> Eq for Key<'bytes>"],["impl Eq for Format"],["impl Eq for FileHash"],["impl Eq for Flags"],["impl Eq for Hash"],["impl<'bytes> Eq for Key<'bytes>"],["impl Eq for CompressionFormat"],["impl Eq for FileHash"],["impl Eq for FileFormat"],["impl Eq for Version"],["impl Eq for CompressionCodec"],["impl Eq for Hash"],["impl Eq for GNMF"],["impl Eq for FileHash"],["impl Eq for DX10"],["impl Eq for Types"],["impl Eq for CompressionResult"],["impl<'bytes> Eq for Key<'bytes>"],["impl<'bytes> Eq for Key<'bytes>"],["impl Eq for Version"],["impl Eq for CompressionLevel"],["impl Eq for Hash"],["impl Eq for DirectoryHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Ord.js b/trait.impl/core/cmp/trait.Ord.js new file mode 100644 index 0000000..daccd5f --- /dev/null +++ b/trait.impl/core/cmp/trait.Ord.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes> Ord for Key<'bytes>"],["impl Ord for FileHash"],["impl<'bytes> Ord for Key<'bytes>"],["impl Ord for Hash"],["impl Ord for DirectoryHash"],["impl Ord for FileHash"],["impl Ord for Version"],["impl Ord for Hash"],["impl<'bytes> Ord for Key<'bytes>"],["impl Ord for Hash"],["impl Ord for FileHash"],["impl<'bytes> Ord for Key<'bytes>"],["impl Ord for Version"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialEq.js b/trait.impl/core/cmp/trait.PartialEq.js new file mode 100644 index 0000000..7842e0e --- /dev/null +++ b/trait.impl/core/cmp/trait.PartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl PartialEq for CompressionFormat"],["impl<'bytes> PartialEq for Key<'bytes>"],["impl<'bytes> PartialEq for Key<'bytes>"],["impl PartialEq for DirectoryHash"],["impl PartialEq for Types"],["impl PartialEq<FileHash> for Hash"],["impl PartialEq for Version"],["impl PartialEq for FileHash"],["impl PartialEq<Hash> for FileHash"],["impl PartialEq for Hash"],["impl PartialEq for Version"],["impl PartialEq for GNMF"],["impl PartialEq for FileHash"],["impl PartialEq for FileHash"],["impl PartialEq<Hash> for DirectoryHash"],["impl PartialEq for Format"],["impl PartialEq<Hash> for FileHash"],["impl PartialEq for CompressionLevel"],["impl PartialEq<Hash> for FileHash"],["impl PartialEq for CompressionCodec"],["impl PartialEq for Hash"],["impl PartialEq for DX10"],["impl PartialEq<FileHash> for Hash"],["impl PartialEq for FileFormat"],["impl PartialEq for Hash"],["impl<'bytes> PartialEq for Key<'bytes>"],["impl PartialEq for Flags"],["impl PartialEq for CompressionResult"],["impl PartialEq<FileHash> for Hash"],["impl PartialEq<DirectoryHash> for Hash"],["impl<'bytes> PartialEq for Key<'bytes>"],["impl PartialEq for Header"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialOrd.js b/trait.impl/core/cmp/trait.PartialOrd.js new file mode 100644 index 0000000..722007d --- /dev/null +++ b/trait.impl/core/cmp/trait.PartialOrd.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes> PartialOrd for Key<'bytes>"],["impl PartialOrd<Hash> for DirectoryHash"],["impl<'bytes> PartialOrd for Key<'bytes>"],["impl PartialOrd for DirectoryHash"],["impl PartialOrd<DirectoryHash> for Hash"],["impl PartialOrd<FileHash> for Hash"],["impl PartialOrd for Hash"],["impl PartialOrd<Hash> for FileHash"],["impl PartialOrd for Hash"],["impl PartialOrd for FileHash"],["impl PartialOrd<Hash> for FileHash"],["impl PartialOrd<FileHash> for Hash"],["impl PartialOrd for Version"],["impl<'bytes> PartialOrd for Key<'bytes>"],["impl<'bytes> PartialOrd for Key<'bytes>"],["impl PartialOrd for Version"],["impl PartialOrd for FileHash"],["impl PartialOrd<Hash> for FileHash"],["impl PartialOrd<FileHash> for Hash"],["impl PartialOrd for Hash"],["impl PartialOrd for FileHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.AsMut.js b/trait.impl/core/convert/trait.AsMut.js new file mode 100644 index 0000000..dcf20c1 --- /dev/null +++ b/trait.impl/core/convert/trait.AsMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl AsMut<Hash> for FileHash"],["impl AsMut<Hash> for FileHash"],["impl AsMut<Hash> for FileHash"],["impl AsMut<Hash> for DirectoryHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.AsRef.js b/trait.impl/core/convert/trait.AsRef.js new file mode 100644 index 0000000..8f85e66 --- /dev/null +++ b/trait.impl/core/convert/trait.AsRef.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl AsRef<Hash> for DirectoryHash"],["impl AsRef<Hash> for FileHash"],["impl AsRef<Hash> for FileHash"],["impl AsRef<Hash> for FileHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.From.js b/trait.impl/core/convert/trait.From.js new file mode 100644 index 0000000..88254af --- /dev/null +++ b/trait.impl/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl From<Options> for ReadOptionsBuilder"],["impl From<Options> for CompressionOptions"],["impl From<Hash> for FileHash"],["impl From<&Options> for WriteOptions"],["impl From<Options> for WriteOptionsBuilder"],["impl From<&Options> for ReadOptionsBuilder"],["impl From<Hash> for FileHash"],["impl From<Options> for ReadOptionsBuilder"],["impl From<Error> for Error"],["impl From<&Options> for CompressionOptionsBuilder"],["impl From<Error> for Error"],["impl From<&Options> for ReadOptions"],["impl<'bytes, const N: usize> From<&'bytes [u8; N]> for File<'bytes>"],["impl From<&Options> for ReadOptions"],["impl From<FileHash> for Hash"],["impl From<TryFromIntError> for Error"],["impl From<&Options> for WriteOptionsBuilder"],["impl From<FileHash> for Hash"],["impl From<Options> for ReadOptions"],["impl From<Options> for ReadOptions"],["impl From<&Options> for ReadOptionsBuilder"],["impl From<FileHash> for Hash"],["impl From<Options> for CompressionOptions"],["impl From<DirectoryHash> for Hash"],["impl From<FileHash> for Key<'static>"],["impl From<FileHash> for Key<'static>"],["impl From<TryFromIntError> for Error"],["impl<T> From<T> for Key<'static>where\n T: Into<BString>,"],["impl From<Error> for Error"],["impl From<&Options> for CompressionOptions"],["impl From<Box<[u8]>> for File<'static>"],["impl<T> From<T> for Key<'static>where\n T: Into<BString>,"],["impl From<DirectoryHash> for Key<'static>"],["impl From<Infallible> for Error"],["impl From<Options> for CompressionOptionsBuilder"],["impl From<&Options> for CompressionOptions"],["impl From<Options> for WriteOptions"],["impl From<Error> for Error"],["impl From<FileHash> for Key<'static>"],["impl From<HResultError> for Error"],["impl<T> From<T> for Key<'static>where\n T: Into<BString>,"],["impl From<Hash> for FileHash"],["impl From<Hash> for DirectoryHash"],["impl<T> From<T> for Key<'static>where\n T: Into<BString>,"],["impl From<DX10> for Header"],["impl<'bytes> From<&'bytes [u8]> for File<'bytes>"],["impl From<Error> for Error"],["impl From<Options> for CompressionOptionsBuilder"],["impl From<GNMF> for Header"],["impl From<&Options> for CompressionOptionsBuilder"],["impl From<TryFromIntError> for Error"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/default/trait.Default.js b/trait.impl/core/default/trait.Default.js new file mode 100644 index 0000000..bb1a6df --- /dev/null +++ b/trait.impl/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Default for CompressionFormat"],["impl Default for DirectoryHash"],["impl Default for Types"],["impl<'bytes> Default for Directory<'bytes>"],["impl<'bytes> Default for File<'bytes>"],["impl Default for Options"],["impl<'bytes> Default for File<'bytes>"],["impl Default for CompressionOptions"],["impl Default for FileHash"],["impl Default for OptionsBuilder"],["impl<'bytes> Default for Chunk<'bytes>"],["impl<'bytes> Default for Archive<'bytes>"],["impl Default for ReadOptions"],["impl Default for OptionsBuilder"],["impl Default for Options"],["impl Default for CompressionLevel"],["impl<'bytes> Default for File<'bytes>"],["impl Default for ReadOptionsBuilder"],["impl Default for ReadOptions"],["impl<'bytes> Default for Archive<'bytes>"],["impl<'bytes> Default for Archive<'bytes>"],["impl Default for CompressionResult"],["impl<'bytes> Default for Key<'bytes>"],["impl Default for ReadOptionsBuilder"],["impl Default for Hash"],["impl Default for CompressionOptionsBuilder"],["impl Default for GNMF"],["impl Default for Format"],["impl Default for FileHash"],["impl Default for Version"],["impl<'bytes> Default for Key<'bytes>"],["impl Default for Hash"],["impl Default for CompressionCodec"],["impl Default for Flags"],["impl Default for WriteOptionsBuilder"],["impl Default for Hash"],["impl Default for WriteOptions"],["impl Default for CompressionOptionsBuilder"],["impl Default for DX10"],["impl Default for Version"],["impl Default for Header"],["impl<'bytes> Default for Key<'bytes>"],["impl Default for CompressionOptions"],["impl Default for FileHash"],["impl<'bytes> Default for Key<'bytes>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/error/trait.Error.js b/trait.impl/core/error/trait.Error.js new file mode 100644 index 0000000..05e2468 --- /dev/null +++ b/trait.impl/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Error for Error"],["impl Error for Error"],["impl Error for Error"],["impl<'bytes> Error for CapacityError<'bytes>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Binary.js b/trait.impl/core/fmt/trait.Binary.js new file mode 100644 index 0000000..0f04693 --- /dev/null +++ b/trait.impl/core/fmt/trait.Binary.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Binary for Types"],["impl Binary for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Debug.js b/trait.impl/core/fmt/trait.Debug.js new file mode 100644 index 0000000..a2a0bf5 --- /dev/null +++ b/trait.impl/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Debug for ReadOptions"],["impl<'bytes> Debug for File<'bytes>"],["impl Debug for Hash"],["impl<'bytes> Debug for Key<'bytes>"],["impl Debug for ReadOptionsBuilder"],["impl<'bytes> Debug for Archive<'bytes>"],["impl<'bytes> Debug for Directory<'bytes>"],["impl Debug for Flags"],["impl Debug for FileHash"],["impl Debug for FileHash"],["impl Debug for Header"],["impl Debug for WriteOptionsBuilder"],["impl Debug for FileFormat"],["impl Debug for Error"],["impl Debug for OptionsBuilder"],["impl Debug for ReadOptions"],["impl Debug for Options"],["impl Debug for DirectoryHash"],["impl<'bytes> Debug for CapacityError<'bytes>"],["impl Debug for CompressionOptionsBuilder"],["impl Debug for Error"],["impl Debug for Options"],["impl Debug for Format"],["impl<'bytes> Debug for Chunk<'bytes>"],["impl<'bytes> Debug for Key<'bytes>"],["impl Debug for Error"],["impl Debug for Hash"],["impl Debug for CompressionLevel"],["impl Debug for WriteOptions"],["impl<'bytes> Debug for File<'bytes>"],["impl Debug for DX10"],["impl Debug for ReadOptionsBuilder"],["impl Debug for FileHash"],["impl Debug for GNMF"],["impl<'bytes> Debug for Archive<'bytes>"],["impl Debug for CompressionOptions"],["impl Debug for CompressionResult"],["impl Debug for CompressionCodec"],["impl Debug for CompressionOptions"],["impl<'bytes> Debug for File<'bytes>"],["impl Debug for Version"],["impl Debug for OptionsBuilder"],["impl Debug for CompressionFormat"],["impl<'bytes> Debug for Key<'bytes>"],["impl Debug for Types"],["impl<'bytes> Debug for Archive<'bytes>"],["impl Debug for Version"],["impl Debug for CompressionOptionsBuilder"],["impl<'bytes> Debug for Key<'bytes>"],["impl Debug for Hash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Display.js b/trait.impl/core/fmt/trait.Display.js new file mode 100644 index 0000000..3a41c4d --- /dev/null +++ b/trait.impl/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes> Display for CapacityError<'bytes>"],["impl Display for Error"],["impl Display for Error"],["impl Display for Error"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.LowerHex.js b/trait.impl/core/fmt/trait.LowerHex.js new file mode 100644 index 0000000..7d13f3b --- /dev/null +++ b/trait.impl/core/fmt/trait.LowerHex.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl LowerHex for Flags"],["impl LowerHex for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Octal.js b/trait.impl/core/fmt/trait.Octal.js new file mode 100644 index 0000000..f5d610a --- /dev/null +++ b/trait.impl/core/fmt/trait.Octal.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Octal for Flags"],["impl Octal for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.UpperHex.js b/trait.impl/core/fmt/trait.UpperHex.js new file mode 100644 index 0000000..2aa7437 --- /dev/null +++ b/trait.impl/core/fmt/trait.UpperHex.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl UpperHex for Flags"],["impl UpperHex for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/iter/traits/collect/trait.Extend.js b/trait.impl/core/iter/traits/collect/trait.Extend.js new file mode 100644 index 0000000..9bd27da --- /dev/null +++ b/trait.impl/core/iter/traits/collect/trait.Extend.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Extend<Types> for Types"],["impl Extend<Flags> for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/iter/traits/collect/trait.FromIterator.js b/trait.impl/core/iter/traits/collect/trait.FromIterator.js new file mode 100644 index 0000000..5e532b5 --- /dev/null +++ b/trait.impl/core/iter/traits/collect/trait.FromIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes> FromIterator<(Key<'bytes>, Directory<'bytes>)> for Archive<'bytes>"],["impl<'bytes> FromIterator<Chunk<'bytes>> for File<'bytes>"],["impl<'bytes> FromIterator<(Key<'bytes>, File<'bytes>)> for Archive<'bytes>"],["impl FromIterator<Flags> for Flags"],["impl<'bytes> FromIterator<(Key<'bytes>, File<'bytes>)> for Archive<'bytes>"],["impl<'bytes> FromIterator<(Key<'bytes>, File<'bytes>)> for Directory<'bytes>"],["impl FromIterator<Types> for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/iter/traits/collect/trait.IntoIterator.js b/trait.impl/core/iter/traits/collect/trait.IntoIterator.js new file mode 100644 index 0000000..43de7e9 --- /dev/null +++ b/trait.impl/core/iter/traits/collect/trait.IntoIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes, 'this> IntoIterator for &'this mut File<'bytes>"],["impl<'bytes> IntoIterator for Directory<'bytes>"],["impl<'bytes> IntoIterator for File<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this Directory<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this File<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this mut Archive<'bytes>"],["impl<'bytes> IntoIterator for Archive<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this Archive<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this mut Archive<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this mut Archive<'bytes>"],["impl IntoIterator for Flags"],["impl<'bytes, 'this> IntoIterator for &'this Archive<'bytes>"],["impl<'bytes> IntoIterator for Archive<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this Archive<'bytes>"],["impl<'bytes, 'this> IntoIterator for &'this mut Directory<'bytes>"],["impl<'bytes> IntoIterator for Archive<'bytes>"],["impl IntoIterator for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Copy.js b/trait.impl/core/marker/trait.Copy.js new file mode 100644 index 0000000..a895c60 --- /dev/null +++ b/trait.impl/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Copy for CompressionLevel"],["impl Copy for ReadOptions"],["impl Copy for Format"],["impl Copy for Version"],["impl Copy for CompressionCodec"],["impl Copy for CompressionOptions"],["impl Copy for Flags"],["impl Copy for CompressionFormat"],["impl Copy for Version"],["impl Copy for FileHash"],["impl Copy for CompressionResult"],["impl Copy for Hash"],["impl Copy for GNMF"],["impl Copy for FileHash"],["impl Copy for DX10"],["impl Copy for WriteOptions"],["impl Copy for Options"],["impl Copy for Hash"],["impl Copy for Options"],["impl Copy for FileFormat"],["impl Copy for DirectoryHash"],["impl Copy for FileHash"],["impl Copy for Hash"],["impl Copy for CompressionOptions"],["impl Copy for Types"],["impl Copy for ReadOptions"],["impl Copy for OptionsBuilder"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Freeze.js b/trait.impl/core/marker/trait.Freeze.js new file mode 100644 index 0000000..4601dd9 --- /dev/null +++ b/trait.impl/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Freeze for OptionsBuilder",1,["ba2::fo4::archive::OptionsBuilder"]],["impl Freeze for Options",1,["ba2::fo4::archive::Options"]],["impl<'bytes> Freeze for Key<'bytes>",1,["ba2::fo4::archive::Key"]],["impl<'bytes> Freeze for Archive<'bytes>",1,["ba2::fo4::archive::Archive"]],["impl Freeze for CompressionOptionsBuilder",1,["ba2::fo4::chunk::CompressionOptionsBuilder"]],["impl Freeze for CompressionOptions",1,["ba2::fo4::chunk::CompressionOptions"]],["impl<'bytes> Freeze for Chunk<'bytes>",1,["ba2::fo4::chunk::Chunk"]],["impl<'bytes> Freeze for CapacityError<'bytes>",1,["ba2::fo4::file::CapacityError"]],["impl Freeze for ReadOptionsBuilder",1,["ba2::fo4::file::ReadOptionsBuilder"]],["impl Freeze for ReadOptions",1,["ba2::fo4::file::ReadOptions"]],["impl Freeze for WriteOptionsBuilder",1,["ba2::fo4::file::WriteOptionsBuilder"]],["impl Freeze for WriteOptions",1,["ba2::fo4::file::WriteOptions"]],["impl Freeze for DX10",1,["ba2::fo4::file::DX10"]],["impl Freeze for GNMF",1,["ba2::fo4::file::GNMF"]],["impl Freeze for Header",1,["ba2::fo4::file::Header"]],["impl<'bytes> Freeze for File<'bytes>",1,["ba2::fo4::file::File"]],["impl Freeze for Hash",1,["ba2::fo4::hashing::Hash"]],["impl Freeze for FileHash",1,["ba2::fo4::hashing::FileHash"]],["impl Freeze for Error",1,["ba2::fo4::Error"]],["impl Freeze for CompressionFormat",1,["ba2::fo4::CompressionFormat"]],["impl Freeze for CompressionLevel",1,["ba2::fo4::CompressionLevel"]],["impl Freeze for Format",1,["ba2::fo4::Format"]],["impl Freeze for Version",1,["ba2::fo4::Version"]],["impl Freeze for FileFormat",1,["ba2::guess::FileFormat"]],["impl<'bytes> Freeze for Key<'bytes>",1,["ba2::tes3::archive::Key"]],["impl<'bytes> Freeze for Archive<'bytes>",1,["ba2::tes3::archive::Archive"]],["impl<'bytes> Freeze for File<'bytes>",1,["ba2::tes3::file::File"]],["impl Freeze for Hash",1,["ba2::tes3::hashing::Hash"]],["impl Freeze for FileHash",1,["ba2::tes3::hashing::FileHash"]],["impl Freeze for Error",1,["ba2::tes3::Error"]],["impl Freeze for Flags",1,["ba2::tes4::archive::Flags"]],["impl Freeze for Types",1,["ba2::tes4::archive::Types"]],["impl<'bytes> Freeze for Key<'bytes>",1,["ba2::tes4::archive::Key"]],["impl Freeze for OptionsBuilder",1,["ba2::tes4::archive::OptionsBuilder"]],["impl Freeze for Options",1,["ba2::tes4::archive::Options"]],["impl<'bytes> Freeze for Archive<'bytes>",1,["ba2::tes4::archive::Archive"]],["impl<'bytes> Freeze for Key<'bytes>",1,["ba2::tes4::directory::Key"]],["impl<'bytes> Freeze for Directory<'bytes>",1,["ba2::tes4::directory::Directory"]],["impl Freeze for CompressionOptionsBuilder",1,["ba2::tes4::file::CompressionOptionsBuilder"]],["impl Freeze for CompressionOptions",1,["ba2::tes4::file::CompressionOptions"]],["impl Freeze for ReadOptionsBuilder",1,["ba2::tes4::file::ReadOptionsBuilder"]],["impl Freeze for ReadOptions",1,["ba2::tes4::file::ReadOptions"]],["impl<'bytes> Freeze for File<'bytes>",1,["ba2::tes4::file::File"]],["impl Freeze for Hash",1,["ba2::tes4::hashing::Hash"]],["impl Freeze for DirectoryHash",1,["ba2::tes4::hashing::DirectoryHash"]],["impl Freeze for FileHash",1,["ba2::tes4::hashing::FileHash"]],["impl Freeze for Error",1,["ba2::tes4::Error"]],["impl Freeze for CompressionCodec",1,["ba2::tes4::CompressionCodec"]],["impl Freeze for Version",1,["ba2::tes4::Version"]],["impl<'borrow> Freeze for Borrowed<'borrow>",1,["ba2::Borrowed"]],["impl<'copy> Freeze for Copied<'copy>",1,["ba2::Copied"]],["impl Freeze for CompressionResult",1,["ba2::CompressionResult"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Send.js b/trait.impl/core/marker/trait.Send.js new file mode 100644 index 0000000..f1baa81 --- /dev/null +++ b/trait.impl/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Send for OptionsBuilder",1,["ba2::fo4::archive::OptionsBuilder"]],["impl Send for Options",1,["ba2::fo4::archive::Options"]],["impl<'bytes> Send for Key<'bytes>",1,["ba2::fo4::archive::Key"]],["impl<'bytes> Send for Archive<'bytes>",1,["ba2::fo4::archive::Archive"]],["impl Send for CompressionOptionsBuilder",1,["ba2::fo4::chunk::CompressionOptionsBuilder"]],["impl Send for CompressionOptions",1,["ba2::fo4::chunk::CompressionOptions"]],["impl<'bytes> Send for Chunk<'bytes>",1,["ba2::fo4::chunk::Chunk"]],["impl<'bytes> Send for CapacityError<'bytes>",1,["ba2::fo4::file::CapacityError"]],["impl Send for ReadOptionsBuilder",1,["ba2::fo4::file::ReadOptionsBuilder"]],["impl Send for ReadOptions",1,["ba2::fo4::file::ReadOptions"]],["impl Send for WriteOptionsBuilder",1,["ba2::fo4::file::WriteOptionsBuilder"]],["impl Send for WriteOptions",1,["ba2::fo4::file::WriteOptions"]],["impl Send for DX10",1,["ba2::fo4::file::DX10"]],["impl Send for GNMF",1,["ba2::fo4::file::GNMF"]],["impl Send for Header",1,["ba2::fo4::file::Header"]],["impl<'bytes> Send for File<'bytes>",1,["ba2::fo4::file::File"]],["impl Send for Hash",1,["ba2::fo4::hashing::Hash"]],["impl Send for FileHash",1,["ba2::fo4::hashing::FileHash"]],["impl Send for Error",1,["ba2::fo4::Error"]],["impl Send for CompressionFormat",1,["ba2::fo4::CompressionFormat"]],["impl Send for CompressionLevel",1,["ba2::fo4::CompressionLevel"]],["impl Send for Format",1,["ba2::fo4::Format"]],["impl Send for Version",1,["ba2::fo4::Version"]],["impl Send for FileFormat",1,["ba2::guess::FileFormat"]],["impl<'bytes> Send for Key<'bytes>",1,["ba2::tes3::archive::Key"]],["impl<'bytes> Send for Archive<'bytes>",1,["ba2::tes3::archive::Archive"]],["impl<'bytes> Send for File<'bytes>",1,["ba2::tes3::file::File"]],["impl Send for Hash",1,["ba2::tes3::hashing::Hash"]],["impl Send for FileHash",1,["ba2::tes3::hashing::FileHash"]],["impl Send for Error",1,["ba2::tes3::Error"]],["impl Send for Flags",1,["ba2::tes4::archive::Flags"]],["impl Send for Types",1,["ba2::tes4::archive::Types"]],["impl<'bytes> Send for Key<'bytes>",1,["ba2::tes4::archive::Key"]],["impl Send for OptionsBuilder",1,["ba2::tes4::archive::OptionsBuilder"]],["impl Send for Options",1,["ba2::tes4::archive::Options"]],["impl<'bytes> Send for Archive<'bytes>",1,["ba2::tes4::archive::Archive"]],["impl<'bytes> Send for Key<'bytes>",1,["ba2::tes4::directory::Key"]],["impl<'bytes> Send for Directory<'bytes>",1,["ba2::tes4::directory::Directory"]],["impl Send for CompressionOptionsBuilder",1,["ba2::tes4::file::CompressionOptionsBuilder"]],["impl Send for CompressionOptions",1,["ba2::tes4::file::CompressionOptions"]],["impl Send for ReadOptionsBuilder",1,["ba2::tes4::file::ReadOptionsBuilder"]],["impl Send for ReadOptions",1,["ba2::tes4::file::ReadOptions"]],["impl<'bytes> Send for File<'bytes>",1,["ba2::tes4::file::File"]],["impl Send for Hash",1,["ba2::tes4::hashing::Hash"]],["impl Send for DirectoryHash",1,["ba2::tes4::hashing::DirectoryHash"]],["impl Send for FileHash",1,["ba2::tes4::hashing::FileHash"]],["impl Send for Error",1,["ba2::tes4::Error"]],["impl Send for CompressionCodec",1,["ba2::tes4::CompressionCodec"]],["impl Send for Version",1,["ba2::tes4::Version"]],["impl<'borrow> Send for Borrowed<'borrow>",1,["ba2::Borrowed"]],["impl<'copy> Send for Copied<'copy>",1,["ba2::Copied"]],["impl Send for CompressionResult",1,["ba2::CompressionResult"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.StructuralEq.js b/trait.impl/core/marker/trait.StructuralEq.js new file mode 100644 index 0000000..1f901bc --- /dev/null +++ b/trait.impl/core/marker/trait.StructuralEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl StructuralEq for Flags"],["impl StructuralEq for CompressionResult"],["impl StructuralEq for GNMF"],["impl StructuralEq for Hash"],["impl StructuralEq for CompressionCodec"],["impl StructuralEq for FileHash"],["impl StructuralEq for FileHash"],["impl StructuralEq for Types"],["impl StructuralEq for Version"],["impl StructuralEq for Version"],["impl StructuralEq for FileFormat"],["impl StructuralEq for CompressionLevel"],["impl StructuralEq for Header"],["impl StructuralEq for FileHash"],["impl StructuralEq for DX10"],["impl StructuralEq for CompressionFormat"],["impl StructuralEq for DirectoryHash"],["impl StructuralEq for Format"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.StructuralPartialEq.js b/trait.impl/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 0000000..76aebd2 --- /dev/null +++ b/trait.impl/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl StructuralPartialEq for FileFormat"],["impl StructuralPartialEq for FileHash"],["impl StructuralPartialEq for FileHash"],["impl StructuralPartialEq for FileHash"],["impl StructuralPartialEq for CompressionCodec"],["impl StructuralPartialEq for DX10"],["impl StructuralPartialEq for Header"],["impl StructuralPartialEq for Version"],["impl StructuralPartialEq for Hash"],["impl StructuralPartialEq for CompressionResult"],["impl StructuralPartialEq for Version"],["impl StructuralPartialEq for CompressionFormat"],["impl StructuralPartialEq for CompressionLevel"],["impl StructuralPartialEq for Format"],["impl StructuralPartialEq for GNMF"],["impl StructuralPartialEq for DirectoryHash"],["impl StructuralPartialEq for Types"],["impl StructuralPartialEq for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Sync.js b/trait.impl/core/marker/trait.Sync.js new file mode 100644 index 0000000..8130f80 --- /dev/null +++ b/trait.impl/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Sync for OptionsBuilder",1,["ba2::fo4::archive::OptionsBuilder"]],["impl Sync for Options",1,["ba2::fo4::archive::Options"]],["impl<'bytes> Sync for Key<'bytes>",1,["ba2::fo4::archive::Key"]],["impl<'bytes> Sync for Archive<'bytes>",1,["ba2::fo4::archive::Archive"]],["impl Sync for CompressionOptionsBuilder",1,["ba2::fo4::chunk::CompressionOptionsBuilder"]],["impl Sync for CompressionOptions",1,["ba2::fo4::chunk::CompressionOptions"]],["impl<'bytes> Sync for Chunk<'bytes>",1,["ba2::fo4::chunk::Chunk"]],["impl<'bytes> Sync for CapacityError<'bytes>",1,["ba2::fo4::file::CapacityError"]],["impl Sync for ReadOptionsBuilder",1,["ba2::fo4::file::ReadOptionsBuilder"]],["impl Sync for ReadOptions",1,["ba2::fo4::file::ReadOptions"]],["impl Sync for WriteOptionsBuilder",1,["ba2::fo4::file::WriteOptionsBuilder"]],["impl Sync for WriteOptions",1,["ba2::fo4::file::WriteOptions"]],["impl Sync for DX10",1,["ba2::fo4::file::DX10"]],["impl Sync for GNMF",1,["ba2::fo4::file::GNMF"]],["impl Sync for Header",1,["ba2::fo4::file::Header"]],["impl<'bytes> Sync for File<'bytes>",1,["ba2::fo4::file::File"]],["impl Sync for Hash",1,["ba2::fo4::hashing::Hash"]],["impl Sync for FileHash",1,["ba2::fo4::hashing::FileHash"]],["impl Sync for Error",1,["ba2::fo4::Error"]],["impl Sync for CompressionFormat",1,["ba2::fo4::CompressionFormat"]],["impl Sync for CompressionLevel",1,["ba2::fo4::CompressionLevel"]],["impl Sync for Format",1,["ba2::fo4::Format"]],["impl Sync for Version",1,["ba2::fo4::Version"]],["impl Sync for FileFormat",1,["ba2::guess::FileFormat"]],["impl<'bytes> Sync for Key<'bytes>",1,["ba2::tes3::archive::Key"]],["impl<'bytes> Sync for Archive<'bytes>",1,["ba2::tes3::archive::Archive"]],["impl<'bytes> Sync for File<'bytes>",1,["ba2::tes3::file::File"]],["impl Sync for Hash",1,["ba2::tes3::hashing::Hash"]],["impl Sync for FileHash",1,["ba2::tes3::hashing::FileHash"]],["impl Sync for Error",1,["ba2::tes3::Error"]],["impl Sync for Flags",1,["ba2::tes4::archive::Flags"]],["impl Sync for Types",1,["ba2::tes4::archive::Types"]],["impl<'bytes> Sync for Key<'bytes>",1,["ba2::tes4::archive::Key"]],["impl Sync for OptionsBuilder",1,["ba2::tes4::archive::OptionsBuilder"]],["impl Sync for Options",1,["ba2::tes4::archive::Options"]],["impl<'bytes> Sync for Archive<'bytes>",1,["ba2::tes4::archive::Archive"]],["impl<'bytes> Sync for Key<'bytes>",1,["ba2::tes4::directory::Key"]],["impl<'bytes> Sync for Directory<'bytes>",1,["ba2::tes4::directory::Directory"]],["impl Sync for CompressionOptionsBuilder",1,["ba2::tes4::file::CompressionOptionsBuilder"]],["impl Sync for CompressionOptions",1,["ba2::tes4::file::CompressionOptions"]],["impl Sync for ReadOptionsBuilder",1,["ba2::tes4::file::ReadOptionsBuilder"]],["impl Sync for ReadOptions",1,["ba2::tes4::file::ReadOptions"]],["impl<'bytes> Sync for File<'bytes>",1,["ba2::tes4::file::File"]],["impl Sync for Hash",1,["ba2::tes4::hashing::Hash"]],["impl Sync for DirectoryHash",1,["ba2::tes4::hashing::DirectoryHash"]],["impl Sync for FileHash",1,["ba2::tes4::hashing::FileHash"]],["impl Sync for Error",1,["ba2::tes4::Error"]],["impl Sync for CompressionCodec",1,["ba2::tes4::CompressionCodec"]],["impl Sync for Version",1,["ba2::tes4::Version"]],["impl<'borrow> Sync for Borrowed<'borrow>",1,["ba2::Borrowed"]],["impl<'copy> Sync for Copied<'copy>",1,["ba2::Copied"]],["impl Sync for CompressionResult",1,["ba2::CompressionResult"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Unpin.js b/trait.impl/core/marker/trait.Unpin.js new file mode 100644 index 0000000..724ebb2 --- /dev/null +++ b/trait.impl/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Unpin for OptionsBuilder",1,["ba2::fo4::archive::OptionsBuilder"]],["impl Unpin for Options",1,["ba2::fo4::archive::Options"]],["impl<'bytes> Unpin for Key<'bytes>",1,["ba2::fo4::archive::Key"]],["impl<'bytes> Unpin for Archive<'bytes>",1,["ba2::fo4::archive::Archive"]],["impl Unpin for CompressionOptionsBuilder",1,["ba2::fo4::chunk::CompressionOptionsBuilder"]],["impl Unpin for CompressionOptions",1,["ba2::fo4::chunk::CompressionOptions"]],["impl<'bytes> Unpin for Chunk<'bytes>",1,["ba2::fo4::chunk::Chunk"]],["impl<'bytes> Unpin for CapacityError<'bytes>",1,["ba2::fo4::file::CapacityError"]],["impl Unpin for ReadOptionsBuilder",1,["ba2::fo4::file::ReadOptionsBuilder"]],["impl Unpin for ReadOptions",1,["ba2::fo4::file::ReadOptions"]],["impl Unpin for WriteOptionsBuilder",1,["ba2::fo4::file::WriteOptionsBuilder"]],["impl Unpin for WriteOptions",1,["ba2::fo4::file::WriteOptions"]],["impl Unpin for DX10",1,["ba2::fo4::file::DX10"]],["impl Unpin for GNMF",1,["ba2::fo4::file::GNMF"]],["impl Unpin for Header",1,["ba2::fo4::file::Header"]],["impl<'bytes> Unpin for File<'bytes>",1,["ba2::fo4::file::File"]],["impl Unpin for Hash",1,["ba2::fo4::hashing::Hash"]],["impl Unpin for FileHash",1,["ba2::fo4::hashing::FileHash"]],["impl Unpin for Error",1,["ba2::fo4::Error"]],["impl Unpin for CompressionFormat",1,["ba2::fo4::CompressionFormat"]],["impl Unpin for CompressionLevel",1,["ba2::fo4::CompressionLevel"]],["impl Unpin for Format",1,["ba2::fo4::Format"]],["impl Unpin for Version",1,["ba2::fo4::Version"]],["impl Unpin for FileFormat",1,["ba2::guess::FileFormat"]],["impl<'bytes> Unpin for Key<'bytes>",1,["ba2::tes3::archive::Key"]],["impl<'bytes> Unpin for Archive<'bytes>",1,["ba2::tes3::archive::Archive"]],["impl<'bytes> Unpin for File<'bytes>",1,["ba2::tes3::file::File"]],["impl Unpin for Hash",1,["ba2::tes3::hashing::Hash"]],["impl Unpin for FileHash",1,["ba2::tes3::hashing::FileHash"]],["impl Unpin for Error",1,["ba2::tes3::Error"]],["impl Unpin for Flags",1,["ba2::tes4::archive::Flags"]],["impl Unpin for Types",1,["ba2::tes4::archive::Types"]],["impl<'bytes> Unpin for Key<'bytes>",1,["ba2::tes4::archive::Key"]],["impl Unpin for OptionsBuilder",1,["ba2::tes4::archive::OptionsBuilder"]],["impl Unpin for Options",1,["ba2::tes4::archive::Options"]],["impl<'bytes> Unpin for Archive<'bytes>",1,["ba2::tes4::archive::Archive"]],["impl<'bytes> Unpin for Key<'bytes>",1,["ba2::tes4::directory::Key"]],["impl<'bytes> Unpin for Directory<'bytes>",1,["ba2::tes4::directory::Directory"]],["impl Unpin for CompressionOptionsBuilder",1,["ba2::tes4::file::CompressionOptionsBuilder"]],["impl Unpin for CompressionOptions",1,["ba2::tes4::file::CompressionOptions"]],["impl Unpin for ReadOptionsBuilder",1,["ba2::tes4::file::ReadOptionsBuilder"]],["impl Unpin for ReadOptions",1,["ba2::tes4::file::ReadOptions"]],["impl<'bytes> Unpin for File<'bytes>",1,["ba2::tes4::file::File"]],["impl Unpin for Hash",1,["ba2::tes4::hashing::Hash"]],["impl Unpin for DirectoryHash",1,["ba2::tes4::hashing::DirectoryHash"]],["impl Unpin for FileHash",1,["ba2::tes4::hashing::FileHash"]],["impl Unpin for Error",1,["ba2::tes4::Error"]],["impl Unpin for CompressionCodec",1,["ba2::tes4::CompressionCodec"]],["impl Unpin for Version",1,["ba2::tes4::Version"]],["impl<'borrow> Unpin for Borrowed<'borrow>",1,["ba2::Borrowed"]],["impl<'copy> Unpin for Copied<'copy>",1,["ba2::Copied"]],["impl Unpin for CompressionResult",1,["ba2::CompressionResult"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/arith/trait.Sub.js b/trait.impl/core/ops/arith/trait.Sub.js new file mode 100644 index 0000000..f792a88 --- /dev/null +++ b/trait.impl/core/ops/arith/trait.Sub.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Sub for Flags"],["impl Sub for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/arith/trait.SubAssign.js b/trait.impl/core/ops/arith/trait.SubAssign.js new file mode 100644 index 0000000..165042b --- /dev/null +++ b/trait.impl/core/ops/arith/trait.SubAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl SubAssign for Types"],["impl SubAssign for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/bit/trait.BitAnd.js b/trait.impl/core/ops/bit/trait.BitAnd.js new file mode 100644 index 0000000..522424c --- /dev/null +++ b/trait.impl/core/ops/bit/trait.BitAnd.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl BitAnd for Types"],["impl BitAnd for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/bit/trait.BitAndAssign.js b/trait.impl/core/ops/bit/trait.BitAndAssign.js new file mode 100644 index 0000000..ef19ad5 --- /dev/null +++ b/trait.impl/core/ops/bit/trait.BitAndAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl BitAndAssign for Flags"],["impl BitAndAssign for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/bit/trait.BitOr.js b/trait.impl/core/ops/bit/trait.BitOr.js new file mode 100644 index 0000000..4e5f9db --- /dev/null +++ b/trait.impl/core/ops/bit/trait.BitOr.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl BitOr for Types"],["impl BitOr for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/bit/trait.BitOrAssign.js b/trait.impl/core/ops/bit/trait.BitOrAssign.js new file mode 100644 index 0000000..f9ecca9 --- /dev/null +++ b/trait.impl/core/ops/bit/trait.BitOrAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl BitOrAssign for Types"],["impl BitOrAssign for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/bit/trait.BitXor.js b/trait.impl/core/ops/bit/trait.BitXor.js new file mode 100644 index 0000000..5c50a47 --- /dev/null +++ b/trait.impl/core/ops/bit/trait.BitXor.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl BitXor for Flags"],["impl BitXor for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/bit/trait.BitXorAssign.js b/trait.impl/core/ops/bit/trait.BitXorAssign.js new file mode 100644 index 0000000..00e699e --- /dev/null +++ b/trait.impl/core/ops/bit/trait.BitXorAssign.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl BitXorAssign for Types"],["impl BitXorAssign for Flags"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/bit/trait.Not.js b/trait.impl/core/ops/bit/trait.Not.js new file mode 100644 index 0000000..bfdcc5b --- /dev/null +++ b/trait.impl/core/ops/bit/trait.Not.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Not for Flags"],["impl Not for Types"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/deref/trait.Deref.js b/trait.impl/core/ops/deref/trait.Deref.js new file mode 100644 index 0000000..5d01a9d --- /dev/null +++ b/trait.impl/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl Deref for FileHash"],["impl Deref for DirectoryHash"],["impl Deref for FileHash"],["impl Deref for FileHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/deref/trait.DerefMut.js b/trait.impl/core/ops/deref/trait.DerefMut.js new file mode 100644 index 0000000..7d37a72 --- /dev/null +++ b/trait.impl/core/ops/deref/trait.DerefMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl DerefMut for FileHash"],["impl DerefMut for DirectoryHash"],["impl DerefMut for FileHash"],["impl DerefMut for FileHash"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/index/trait.Index.js b/trait.impl/core/ops/index/trait.Index.js new file mode 100644 index 0000000..65ad993 --- /dev/null +++ b/trait.impl/core/ops/index/trait.Index.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes> Index<usize> for File<'bytes>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/index/trait.IndexMut.js b/trait.impl/core/ops/index/trait.IndexMut.js new file mode 100644 index 0000000..be6f6f0 --- /dev/null +++ b/trait.impl/core/ops/index/trait.IndexMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl<'bytes> IndexMut<usize> for File<'bytes>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 0000000..6038c40 --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl RefUnwindSafe for OptionsBuilder",1,["ba2::fo4::archive::OptionsBuilder"]],["impl RefUnwindSafe for Options",1,["ba2::fo4::archive::Options"]],["impl<'bytes> RefUnwindSafe for Key<'bytes>",1,["ba2::fo4::archive::Key"]],["impl<'bytes> RefUnwindSafe for Archive<'bytes>",1,["ba2::fo4::archive::Archive"]],["impl RefUnwindSafe for CompressionOptionsBuilder",1,["ba2::fo4::chunk::CompressionOptionsBuilder"]],["impl RefUnwindSafe for CompressionOptions",1,["ba2::fo4::chunk::CompressionOptions"]],["impl<'bytes> RefUnwindSafe for Chunk<'bytes>",1,["ba2::fo4::chunk::Chunk"]],["impl<'bytes> RefUnwindSafe for CapacityError<'bytes>",1,["ba2::fo4::file::CapacityError"]],["impl RefUnwindSafe for ReadOptionsBuilder",1,["ba2::fo4::file::ReadOptionsBuilder"]],["impl RefUnwindSafe for ReadOptions",1,["ba2::fo4::file::ReadOptions"]],["impl RefUnwindSafe for WriteOptionsBuilder",1,["ba2::fo4::file::WriteOptionsBuilder"]],["impl RefUnwindSafe for WriteOptions",1,["ba2::fo4::file::WriteOptions"]],["impl RefUnwindSafe for DX10",1,["ba2::fo4::file::DX10"]],["impl RefUnwindSafe for GNMF",1,["ba2::fo4::file::GNMF"]],["impl RefUnwindSafe for Header",1,["ba2::fo4::file::Header"]],["impl<'bytes> RefUnwindSafe for File<'bytes>",1,["ba2::fo4::file::File"]],["impl RefUnwindSafe for Hash",1,["ba2::fo4::hashing::Hash"]],["impl RefUnwindSafe for FileHash",1,["ba2::fo4::hashing::FileHash"]],["impl !RefUnwindSafe for Error",1,["ba2::fo4::Error"]],["impl RefUnwindSafe for CompressionFormat",1,["ba2::fo4::CompressionFormat"]],["impl RefUnwindSafe for CompressionLevel",1,["ba2::fo4::CompressionLevel"]],["impl RefUnwindSafe for Format",1,["ba2::fo4::Format"]],["impl RefUnwindSafe for Version",1,["ba2::fo4::Version"]],["impl RefUnwindSafe for FileFormat",1,["ba2::guess::FileFormat"]],["impl<'bytes> RefUnwindSafe for Key<'bytes>",1,["ba2::tes3::archive::Key"]],["impl<'bytes> RefUnwindSafe for Archive<'bytes>",1,["ba2::tes3::archive::Archive"]],["impl<'bytes> RefUnwindSafe for File<'bytes>",1,["ba2::tes3::file::File"]],["impl RefUnwindSafe for Hash",1,["ba2::tes3::hashing::Hash"]],["impl RefUnwindSafe for FileHash",1,["ba2::tes3::hashing::FileHash"]],["impl !RefUnwindSafe for Error",1,["ba2::tes3::Error"]],["impl RefUnwindSafe for Flags",1,["ba2::tes4::archive::Flags"]],["impl RefUnwindSafe for Types",1,["ba2::tes4::archive::Types"]],["impl<'bytes> RefUnwindSafe for Key<'bytes>",1,["ba2::tes4::archive::Key"]],["impl RefUnwindSafe for OptionsBuilder",1,["ba2::tes4::archive::OptionsBuilder"]],["impl RefUnwindSafe for Options",1,["ba2::tes4::archive::Options"]],["impl<'bytes> RefUnwindSafe for Archive<'bytes>",1,["ba2::tes4::archive::Archive"]],["impl<'bytes> RefUnwindSafe for Key<'bytes>",1,["ba2::tes4::directory::Key"]],["impl<'bytes> RefUnwindSafe for Directory<'bytes>",1,["ba2::tes4::directory::Directory"]],["impl RefUnwindSafe for CompressionOptionsBuilder",1,["ba2::tes4::file::CompressionOptionsBuilder"]],["impl RefUnwindSafe for CompressionOptions",1,["ba2::tes4::file::CompressionOptions"]],["impl RefUnwindSafe for ReadOptionsBuilder",1,["ba2::tes4::file::ReadOptionsBuilder"]],["impl RefUnwindSafe for ReadOptions",1,["ba2::tes4::file::ReadOptions"]],["impl<'bytes> RefUnwindSafe for File<'bytes>",1,["ba2::tes4::file::File"]],["impl RefUnwindSafe for Hash",1,["ba2::tes4::hashing::Hash"]],["impl RefUnwindSafe for DirectoryHash",1,["ba2::tes4::hashing::DirectoryHash"]],["impl RefUnwindSafe for FileHash",1,["ba2::tes4::hashing::FileHash"]],["impl !RefUnwindSafe for Error",1,["ba2::tes4::Error"]],["impl RefUnwindSafe for CompressionCodec",1,["ba2::tes4::CompressionCodec"]],["impl RefUnwindSafe for Version",1,["ba2::tes4::Version"]],["impl<'borrow> RefUnwindSafe for Borrowed<'borrow>",1,["ba2::Borrowed"]],["impl<'copy> RefUnwindSafe for Copied<'copy>",1,["ba2::Copied"]],["impl RefUnwindSafe for CompressionResult",1,["ba2::CompressionResult"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 0000000..45e9143 --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ba2":[["impl UnwindSafe for OptionsBuilder",1,["ba2::fo4::archive::OptionsBuilder"]],["impl UnwindSafe for Options",1,["ba2::fo4::archive::Options"]],["impl<'bytes> UnwindSafe for Key<'bytes>",1,["ba2::fo4::archive::Key"]],["impl<'bytes> UnwindSafe for Archive<'bytes>",1,["ba2::fo4::archive::Archive"]],["impl UnwindSafe for CompressionOptionsBuilder",1,["ba2::fo4::chunk::CompressionOptionsBuilder"]],["impl UnwindSafe for CompressionOptions",1,["ba2::fo4::chunk::CompressionOptions"]],["impl<'bytes> UnwindSafe for Chunk<'bytes>",1,["ba2::fo4::chunk::Chunk"]],["impl<'bytes> UnwindSafe for CapacityError<'bytes>",1,["ba2::fo4::file::CapacityError"]],["impl UnwindSafe for ReadOptionsBuilder",1,["ba2::fo4::file::ReadOptionsBuilder"]],["impl UnwindSafe for ReadOptions",1,["ba2::fo4::file::ReadOptions"]],["impl UnwindSafe for WriteOptionsBuilder",1,["ba2::fo4::file::WriteOptionsBuilder"]],["impl UnwindSafe for WriteOptions",1,["ba2::fo4::file::WriteOptions"]],["impl UnwindSafe for DX10",1,["ba2::fo4::file::DX10"]],["impl UnwindSafe for GNMF",1,["ba2::fo4::file::GNMF"]],["impl UnwindSafe for Header",1,["ba2::fo4::file::Header"]],["impl<'bytes> UnwindSafe for File<'bytes>",1,["ba2::fo4::file::File"]],["impl UnwindSafe for Hash",1,["ba2::fo4::hashing::Hash"]],["impl UnwindSafe for FileHash",1,["ba2::fo4::hashing::FileHash"]],["impl !UnwindSafe for Error",1,["ba2::fo4::Error"]],["impl UnwindSafe for CompressionFormat",1,["ba2::fo4::CompressionFormat"]],["impl UnwindSafe for CompressionLevel",1,["ba2::fo4::CompressionLevel"]],["impl UnwindSafe for Format",1,["ba2::fo4::Format"]],["impl UnwindSafe for Version",1,["ba2::fo4::Version"]],["impl UnwindSafe for FileFormat",1,["ba2::guess::FileFormat"]],["impl<'bytes> UnwindSafe for Key<'bytes>",1,["ba2::tes3::archive::Key"]],["impl<'bytes> UnwindSafe for Archive<'bytes>",1,["ba2::tes3::archive::Archive"]],["impl<'bytes> UnwindSafe for File<'bytes>",1,["ba2::tes3::file::File"]],["impl UnwindSafe for Hash",1,["ba2::tes3::hashing::Hash"]],["impl UnwindSafe for FileHash",1,["ba2::tes3::hashing::FileHash"]],["impl !UnwindSafe for Error",1,["ba2::tes3::Error"]],["impl UnwindSafe for Flags",1,["ba2::tes4::archive::Flags"]],["impl UnwindSafe for Types",1,["ba2::tes4::archive::Types"]],["impl<'bytes> UnwindSafe for Key<'bytes>",1,["ba2::tes4::archive::Key"]],["impl UnwindSafe for OptionsBuilder",1,["ba2::tes4::archive::OptionsBuilder"]],["impl UnwindSafe for Options",1,["ba2::tes4::archive::Options"]],["impl<'bytes> UnwindSafe for Archive<'bytes>",1,["ba2::tes4::archive::Archive"]],["impl<'bytes> UnwindSafe for Key<'bytes>",1,["ba2::tes4::directory::Key"]],["impl<'bytes> UnwindSafe for Directory<'bytes>",1,["ba2::tes4::directory::Directory"]],["impl UnwindSafe for CompressionOptionsBuilder",1,["ba2::tes4::file::CompressionOptionsBuilder"]],["impl UnwindSafe for CompressionOptions",1,["ba2::tes4::file::CompressionOptions"]],["impl UnwindSafe for ReadOptionsBuilder",1,["ba2::tes4::file::ReadOptionsBuilder"]],["impl UnwindSafe for ReadOptions",1,["ba2::tes4::file::ReadOptions"]],["impl<'bytes> UnwindSafe for File<'bytes>",1,["ba2::tes4::file::File"]],["impl UnwindSafe for Hash",1,["ba2::tes4::hashing::Hash"]],["impl UnwindSafe for DirectoryHash",1,["ba2::tes4::hashing::DirectoryHash"]],["impl UnwindSafe for FileHash",1,["ba2::tes4::hashing::FileHash"]],["impl !UnwindSafe for Error",1,["ba2::tes4::Error"]],["impl UnwindSafe for CompressionCodec",1,["ba2::tes4::CompressionCodec"]],["impl UnwindSafe for Version",1,["ba2::tes4::Version"]],["impl<'borrow> UnwindSafe for Borrowed<'borrow>",1,["ba2::Borrowed"]],["impl<'copy> UnwindSafe for Copied<'copy>",1,["ba2::Copied"]],["impl UnwindSafe for CompressionResult",1,["ba2::CompressionResult"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/type.impl/core/result/enum.Result.js b/type.impl/core/result/enum.Result.js new file mode 100644 index 0000000..ece7b27 --- /dev/null +++ b/type.impl/core/result/enum.Result.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"ba2":[["
source§

impl<T, E> Result<T, E>

1.0.0 (const: 1.48.0) · source

pub const fn is_ok(&self) -> bool

Returns true if the result is Ok.

\n
Examples
\n
let x: Result<i32, &str> = Ok(-3);\nassert_eq!(x.is_ok(), true);\n\nlet x: Result<i32, &str> = Err("Some error message");\nassert_eq!(x.is_ok(), false);
\n
1.70.0 · source

pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool

Returns true if the result is Ok and the value inside of it matches a predicate.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.is_ok_and(|x| x > 1), true);\n\nlet x: Result<u32, &str> = Ok(0);\nassert_eq!(x.is_ok_and(|x| x > 1), false);\n\nlet x: Result<u32, &str> = Err("hey");\nassert_eq!(x.is_ok_and(|x| x > 1), false);
\n
1.0.0 (const: 1.48.0) · source

pub const fn is_err(&self) -> bool

Returns true if the result is Err.

\n
Examples
\n
let x: Result<i32, &str> = Ok(-3);\nassert_eq!(x.is_err(), false);\n\nlet x: Result<i32, &str> = Err("Some error message");\nassert_eq!(x.is_err(), true);
\n
1.70.0 · source

pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool

Returns true if the result is Err and the value inside of it matches a predicate.

\n
Examples
\n
use std::io::{Error, ErrorKind};\n\nlet x: Result<u32, Error> = Err(Error::new(ErrorKind::NotFound, "!"));\nassert_eq!(x.is_err_and(|x| x.kind() == ErrorKind::NotFound), true);\n\nlet x: Result<u32, Error> = Err(Error::new(ErrorKind::PermissionDenied, "!"));\nassert_eq!(x.is_err_and(|x| x.kind() == ErrorKind::NotFound), false);\n\nlet x: Result<u32, Error> = Ok(123);\nassert_eq!(x.is_err_and(|x| x.kind() == ErrorKind::NotFound), false);
\n
1.0.0 · source

pub fn ok(self) -> Option<T>

Converts from Result<T, E> to Option<T>.

\n

Converts self into an Option<T>, consuming self,\nand discarding the error, if any.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.ok(), Some(2));\n\nlet x: Result<u32, &str> = Err("Nothing here");\nassert_eq!(x.ok(), None);
\n
1.0.0 · source

pub fn err(self) -> Option<E>

Converts from Result<T, E> to Option<E>.

\n

Converts self into an Option<E>, consuming self,\nand discarding the success value, if any.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.err(), None);\n\nlet x: Result<u32, &str> = Err("Nothing here");\nassert_eq!(x.err(), Some("Nothing here"));
\n
1.0.0 (const: 1.48.0) · source

pub const fn as_ref(&self) -> Result<&T, &E>

Converts from &Result<T, E> to Result<&T, &E>.

\n

Produces a new Result, containing a reference\ninto the original, leaving the original in place.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.as_ref(), Ok(&2));\n\nlet x: Result<u32, &str> = Err("Error");\nassert_eq!(x.as_ref(), Err(&"Error"));
\n
1.0.0 (const: unstable) · source

pub fn as_mut(&mut self) -> Result<&mut T, &mut E>

Converts from &mut Result<T, E> to Result<&mut T, &mut E>.

\n
Examples
\n
fn mutate(r: &mut Result<i32, i32>) {\n    match r.as_mut() {\n        Ok(v) => *v = 42,\n        Err(e) => *e = 0,\n    }\n}\n\nlet mut x: Result<i32, i32> = Ok(2);\nmutate(&mut x);\nassert_eq!(x.unwrap(), 42);\n\nlet mut x: Result<i32, i32> = Err(13);\nmutate(&mut x);\nassert_eq!(x.unwrap_err(), 0);
\n
1.0.0 · source

pub fn map<U, F>(self, op: F) -> Result<U, E>where\n F: FnOnce(T) -> U,

Maps a Result<T, E> to Result<U, E> by applying a function to a\ncontained Ok value, leaving an Err value untouched.

\n

This function can be used to compose the results of two functions.

\n
Examples
\n

Print the numbers on each line of a string multiplied by two.

\n\n
let line = "1\\n2\\n3\\n4\\n";\n\nfor num in line.lines() {\n    match num.parse::<i32>().map(|i| i * 2) {\n        Ok(n) => println!("{n}"),\n        Err(..) => {}\n    }\n}
\n
1.41.0 · source

pub fn map_or<U, F>(self, default: U, f: F) -> Uwhere\n F: FnOnce(T) -> U,

Returns the provided default (if Err), or\napplies a function to the contained value (if Ok).

\n

Arguments passed to map_or are eagerly evaluated; if you are passing\nthe result of a function call, it is recommended to use map_or_else,\nwhich is lazily evaluated.

\n
Examples
\n
let x: Result<_, &str> = Ok("foo");\nassert_eq!(x.map_or(42, |v| v.len()), 3);\n\nlet x: Result<&str, _> = Err("bar");\nassert_eq!(x.map_or(42, |v| v.len()), 42);
\n
1.41.0 · source

pub fn map_or_else<U, D, F>(self, default: D, f: F) -> Uwhere\n D: FnOnce(E) -> U,\n F: FnOnce(T) -> U,

Maps a Result<T, E> to U by applying fallback function default to\na contained Err value, or function f to a contained Ok value.

\n

This function can be used to unpack a successful result\nwhile handling an error.

\n
Examples
\n
let k = 21;\n\nlet x : Result<_, &str> = Ok("foo");\nassert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 3);\n\nlet x : Result<&str, _> = Err("bar");\nassert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 42);
\n
1.0.0 · source

pub fn map_err<F, O>(self, op: O) -> Result<T, F>where\n O: FnOnce(E) -> F,

Maps a Result<T, E> to Result<T, F> by applying a function to a\ncontained Err value, leaving an Ok value untouched.

\n

This function can be used to pass through a successful result while handling\nan error.

\n
Examples
\n
fn stringify(x: u32) -> String { format!("error code: {x}") }\n\nlet x: Result<u32, u32> = Ok(2);\nassert_eq!(x.map_err(stringify), Ok(2));\n\nlet x: Result<u32, u32> = Err(13);\nassert_eq!(x.map_err(stringify), Err("error code: 13".to_string()));
\n
source

pub fn inspect<F>(self, f: F) -> Result<T, E>where\n F: FnOnce(&T),

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

Calls the provided closure with a reference to the contained value (if Ok).

\n
Examples
\n
#![feature(result_option_inspect)]\n\nlet x: u8 = "4"\n    .parse::<u8>()\n    .inspect(|x| println!("original: {x}"))\n    .map(|x| x.pow(3))\n    .expect("failed to parse number");
\n
source

pub fn inspect_err<F>(self, f: F) -> Result<T, E>where\n F: FnOnce(&E),

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

Calls the provided closure with a reference to the contained error (if Err).

\n
Examples
\n
#![feature(result_option_inspect)]\n\nuse std::{fs, io};\n\nfn read() -> io::Result<String> {\n    fs::read_to_string("address.txt")\n        .inspect_err(|e| eprintln!("failed to read file: {e}"))\n}
\n
1.47.0 · source

pub fn as_deref(&self) -> Result<&<T as Deref>::Target, &E>where\n T: Deref,

Converts from Result<T, E> (or &Result<T, E>) to Result<&<T as Deref>::Target, &E>.

\n

Coerces the Ok variant of the original Result via Deref\nand returns the new Result.

\n
Examples
\n
let x: Result<String, u32> = Ok("hello".to_string());\nlet y: Result<&str, &u32> = Ok("hello");\nassert_eq!(x.as_deref(), y);\n\nlet x: Result<String, u32> = Err(42);\nlet y: Result<&str, &u32> = Err(&42);\nassert_eq!(x.as_deref(), y);
\n
1.47.0 · source

pub fn as_deref_mut(&mut self) -> Result<&mut <T as Deref>::Target, &mut E>where\n T: DerefMut,

Converts from Result<T, E> (or &mut Result<T, E>) to Result<&mut <T as DerefMut>::Target, &mut E>.

\n

Coerces the Ok variant of the original Result via DerefMut\nand returns the new Result.

\n
Examples
\n
let mut s = "HELLO".to_string();\nlet mut x: Result<String, u32> = Ok("hello".to_string());\nlet y: Result<&mut str, &mut u32> = Ok(&mut s);\nassert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);\n\nlet mut i = 42;\nlet mut x: Result<String, u32> = Err(42);\nlet y: Result<&mut str, &mut u32> = Err(&mut i);\nassert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
\n
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the possibly contained value.

\n

The iterator yields one value if the result is Result::Ok, otherwise none.

\n
Examples
\n
let x: Result<u32, &str> = Ok(7);\nassert_eq!(x.iter().next(), Some(&7));\n\nlet x: Result<u32, &str> = Err("nothing!");\nassert_eq!(x.iter().next(), None);
\n
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns a mutable iterator over the possibly contained value.

\n

The iterator yields one value if the result is Result::Ok, otherwise none.

\n
Examples
\n
let mut x: Result<u32, &str> = Ok(7);\nmatch x.iter_mut().next() {\n    Some(v) => *v = 40,\n    None => {},\n}\nassert_eq!(x, Ok(40));\n\nlet mut x: Result<u32, &str> = Err("nothing!");\nassert_eq!(x.iter_mut().next(), None);
\n
1.4.0 · source

pub fn expect(self, msg: &str) -> Twhere\n E: Debug,

Returns the contained Ok value, consuming the self value.

\n

Because this function may panic, its use is generally discouraged.\nInstead, prefer to use pattern matching and handle the Err\ncase explicitly, or call unwrap_or, unwrap_or_else, or\nunwrap_or_default.

\n
Panics
\n

Panics if the value is an Err, with a panic message including the\npassed message, and the content of the Err.

\n
Examples
\n
let x: Result<u32, &str> = Err("emergency failure");\nx.expect("Testing expect"); // panics with `Testing expect: emergency failure`
\n
Recommended Message Style
\n

We recommend that expect messages are used to describe the reason you\nexpect the Result should be Ok.

\n\n
let path = std::env::var("IMPORTANT_PATH")\n    .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
\n

Hint: If you’re having trouble remembering how to phrase expect\nerror messages remember to focus on the word “should” as in “env\nvariable should be set by blah” or “the given binary should be available\nand executable by the current user”.

\n

For more detail on expect message styles and the reasoning behind our recommendation please\nrefer to the section on “Common Message\nStyles” in the\nstd::error module docs.

\n
1.0.0 · source

pub fn unwrap(self) -> Twhere\n E: Debug,

Returns the contained Ok value, consuming the self value.

\n

Because this function may panic, its use is generally discouraged.\nInstead, prefer to use pattern matching and handle the Err\ncase explicitly, or call unwrap_or, unwrap_or_else, or\nunwrap_or_default.

\n
Panics
\n

Panics if the value is an Err, with a panic message provided by the\nErr’s value.

\n
Examples
\n

Basic usage:

\n\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.unwrap(), 2);
\n\n
let x: Result<u32, &str> = Err("emergency failure");\nx.unwrap(); // panics with `emergency failure`
\n
1.16.0 · source

pub fn unwrap_or_default(self) -> Twhere\n T: Default,

Returns the contained Ok value or a default

\n

Consumes the self argument then, if Ok, returns the contained\nvalue, otherwise if Err, returns the default value for that\ntype.

\n
Examples
\n

Converts a string to an integer, turning poorly-formed strings\ninto 0 (the default value for integers). parse converts\na string to any other type that implements FromStr, returning an\nErr on error.

\n\n
let good_year_from_input = "1909";\nlet bad_year_from_input = "190blarg";\nlet good_year = good_year_from_input.parse().unwrap_or_default();\nlet bad_year = bad_year_from_input.parse().unwrap_or_default();\n\nassert_eq!(1909, good_year);\nassert_eq!(0, bad_year);
\n
1.17.0 · source

pub fn expect_err(self, msg: &str) -> Ewhere\n T: Debug,

Returns the contained Err value, consuming the self value.

\n
Panics
\n

Panics if the value is an Ok, with a panic message including the\npassed message, and the content of the Ok.

\n
Examples
\n
let x: Result<u32, &str> = Ok(10);\nx.expect_err("Testing expect_err"); // panics with `Testing expect_err: 10`
\n
1.0.0 · source

pub fn unwrap_err(self) -> Ewhere\n T: Debug,

Returns the contained Err value, consuming the self value.

\n
Panics
\n

Panics if the value is an Ok, with a custom panic message provided\nby the Ok’s value.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nx.unwrap_err(); // panics with `2`
\n\n
let x: Result<u32, &str> = Err("emergency failure");\nassert_eq!(x.unwrap_err(), "emergency failure");
\n
source

pub fn into_ok(self) -> Twhere\n E: Into<!>,

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

Returns the contained Ok value, but never panics.

\n

Unlike unwrap, this method is known to never panic on the\nresult types it is implemented for. Therefore, it can be used\ninstead of unwrap as a maintainability safeguard that will fail\nto compile if the error type of the Result is later changed\nto an error that can actually occur.

\n
Examples
\n
\nfn only_good_news() -> Result<String, !> {\n    Ok("this is fine".into())\n}\n\nlet s: String = only_good_news().into_ok();\nprintln!("{s}");
\n
source

pub fn into_err(self) -> Ewhere\n T: Into<!>,

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

Returns the contained Err value, but never panics.

\n

Unlike unwrap_err, this method is known to never panic on the\nresult types it is implemented for. Therefore, it can be used\ninstead of unwrap_err as a maintainability safeguard that will fail\nto compile if the ok type of the Result is later changed\nto a type that can actually occur.

\n
Examples
\n
\nfn only_bad_news() -> Result<!, String> {\n    Err("Oops, it failed".into())\n}\n\nlet error: String = only_bad_news().into_err();\nprintln!("{error}");
\n
1.0.0 · source

pub fn and<U>(self, res: Result<U, E>) -> Result<U, E>

Returns res if the result is Ok, otherwise returns the Err value of self.

\n

Arguments passed to and are eagerly evaluated; if you are passing the\nresult of a function call, it is recommended to use and_then, which is\nlazily evaluated.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nlet y: Result<&str, &str> = Err("late error");\nassert_eq!(x.and(y), Err("late error"));\n\nlet x: Result<u32, &str> = Err("early error");\nlet y: Result<&str, &str> = Ok("foo");\nassert_eq!(x.and(y), Err("early error"));\n\nlet x: Result<u32, &str> = Err("not a 2");\nlet y: Result<&str, &str> = Err("late error");\nassert_eq!(x.and(y), Err("not a 2"));\n\nlet x: Result<u32, &str> = Ok(2);\nlet y: Result<&str, &str> = Ok("different result type");\nassert_eq!(x.and(y), Ok("different result type"));
\n
1.0.0 · source

pub fn and_then<U, F>(self, op: F) -> Result<U, E>where\n F: FnOnce(T) -> Result<U, E>,

Calls op if the result is Ok, otherwise returns the Err value of self.

\n

This function can be used for control flow based on Result values.

\n
Examples
\n
fn sq_then_to_string(x: u32) -> Result<String, &'static str> {\n    x.checked_mul(x).map(|sq| sq.to_string()).ok_or("overflowed")\n}\n\nassert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string()));\nassert_eq!(Ok(1_000_000).and_then(sq_then_to_string), Err("overflowed"));\nassert_eq!(Err("not a number").and_then(sq_then_to_string), Err("not a number"));
\n

Often used to chain fallible operations that may return Err.

\n\n
use std::{io::ErrorKind, path::Path};\n\n// Note: on Windows "/" maps to "C:\\"\nlet root_modified_time = Path::new("/").metadata().and_then(|md| md.modified());\nassert!(root_modified_time.is_ok());\n\nlet should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified());\nassert!(should_fail.is_err());\nassert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound);
\n
1.0.0 · source

pub fn or<F>(self, res: Result<T, F>) -> Result<T, F>

Returns res if the result is Err, otherwise returns the Ok value of self.

\n

Arguments passed to or are eagerly evaluated; if you are passing the\nresult of a function call, it is recommended to use or_else, which is\nlazily evaluated.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nlet y: Result<u32, &str> = Err("late error");\nassert_eq!(x.or(y), Ok(2));\n\nlet x: Result<u32, &str> = Err("early error");\nlet y: Result<u32, &str> = Ok(2);\nassert_eq!(x.or(y), Ok(2));\n\nlet x: Result<u32, &str> = Err("not a 2");\nlet y: Result<u32, &str> = Err("late error");\nassert_eq!(x.or(y), Err("late error"));\n\nlet x: Result<u32, &str> = Ok(2);\nlet y: Result<u32, &str> = Ok(100);\nassert_eq!(x.or(y), Ok(2));
\n
1.0.0 · source

pub fn or_else<F, O>(self, op: O) -> Result<T, F>where\n O: FnOnce(E) -> Result<T, F>,

Calls op if the result is Err, otherwise returns the Ok value of self.

\n

This function can be used for control flow based on result values.

\n
Examples
\n
fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }\nfn err(x: u32) -> Result<u32, u32> { Err(x) }\n\nassert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2));\nassert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2));\nassert_eq!(Err(3).or_else(sq).or_else(err), Ok(9));\nassert_eq!(Err(3).or_else(err).or_else(err), Err(3));
\n
1.0.0 · source

pub fn unwrap_or(self, default: T) -> T

Returns the contained Ok value or a provided default.

\n

Arguments passed to unwrap_or are eagerly evaluated; if you are passing\nthe result of a function call, it is recommended to use unwrap_or_else,\nwhich is lazily evaluated.

\n
Examples
\n
let default = 2;\nlet x: Result<u32, &str> = Ok(9);\nassert_eq!(x.unwrap_or(default), 9);\n\nlet x: Result<u32, &str> = Err("error");\nassert_eq!(x.unwrap_or(default), default);
\n
1.0.0 · source

pub fn unwrap_or_else<F>(self, op: F) -> Twhere\n F: FnOnce(E) -> T,

Returns the contained Ok value or computes it from a closure.

\n
Examples
\n
fn count(x: &str) -> usize { x.len() }\n\nassert_eq!(Ok(2).unwrap_or_else(count), 2);\nassert_eq!(Err("foo").unwrap_or_else(count), 3);
\n
1.58.0 · source

pub unsafe fn unwrap_unchecked(self) -> T

Returns the contained Ok value, consuming the self value,\nwithout checking that the value is not an Err.

\n
Safety
\n

Calling this method on an Err is undefined behavior.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(unsafe { x.unwrap_unchecked() }, 2);
\n\n
let x: Result<u32, &str> = Err("emergency failure");\nunsafe { x.unwrap_unchecked(); } // Undefined behavior!
\n
1.58.0 · source

pub unsafe fn unwrap_err_unchecked(self) -> E

Returns the contained Err value, consuming the self value,\nwithout checking that the value is not an Ok.

\n
Safety
\n

Calling this method on an Ok is undefined behavior.

\n
Examples
\n
let x: Result<u32, &str> = Ok(2);\nunsafe { x.unwrap_err_unchecked() }; // Undefined behavior!
\n\n
let x: Result<u32, &str> = Err("emergency failure");\nassert_eq!(unsafe { x.unwrap_err_unchecked() }, "emergency failure");
\n
",0,"ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E> Result<&T, E>

1.59.0 · source

pub fn copied(self) -> Result<T, E>where\n T: Copy,

Maps a Result<&T, E> to a Result<T, E> by copying the contents of the\nOk part.

\n
Examples
\n
let val = 12;\nlet x: Result<&i32, i32> = Ok(&val);\nassert_eq!(x, Ok(&12));\nlet copied = x.copied();\nassert_eq!(copied, Ok(12));
\n
1.59.0 · source

pub fn cloned(self) -> Result<T, E>where\n T: Clone,

Maps a Result<&T, E> to a Result<T, E> by cloning the contents of the\nOk part.

\n
Examples
\n
let val = 12;\nlet x: Result<&i32, i32> = Ok(&val);\nassert_eq!(x, Ok(&12));\nlet cloned = x.cloned();\nassert_eq!(cloned, Ok(12));
\n
",0,"ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E> Result<&mut T, E>

1.59.0 · source

pub fn copied(self) -> Result<T, E>where\n T: Copy,

Maps a Result<&mut T, E> to a Result<T, E> by copying the contents of the\nOk part.

\n
Examples
\n
let mut val = 12;\nlet x: Result<&mut i32, i32> = Ok(&mut val);\nassert_eq!(x, Ok(&mut 12));\nlet copied = x.copied();\nassert_eq!(copied, Ok(12));
\n
1.59.0 · source

pub fn cloned(self) -> Result<T, E>where\n T: Clone,

Maps a Result<&mut T, E> to a Result<T, E> by cloning the contents of the\nOk part.

\n
Examples
\n
let mut val = 12;\nlet x: Result<&mut i32, i32> = Ok(&mut val);\nassert_eq!(x, Ok(&mut 12));\nlet cloned = x.cloned();\nassert_eq!(cloned, Ok(12));
\n
",0,"ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E> Result<Option<T>, E>

1.33.0 (const: unstable) · source

pub fn transpose(self) -> Option<Result<T, E>>

Transposes a Result of an Option into an Option of a Result.

\n

Ok(None) will be mapped to None.\nOk(Some(_)) and Err(_) will be mapped to Some(Ok(_)) and Some(Err(_)).

\n
Examples
\n
#[derive(Debug, Eq, PartialEq)]\nstruct SomeErr;\n\nlet x: Result<Option<i32>, SomeErr> = Ok(Some(5));\nlet y: Option<Result<i32, SomeErr>> = Some(Ok(5));\nassert_eq!(x.transpose(), y);
\n
",0,"ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E> Result<Result<T, E>, E>

source

pub fn flatten(self) -> Result<T, E>

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

Converts from Result<Result<T, E>, E> to Result<T, E>

\n
Examples
\n
#![feature(result_flattening)]\nlet x: Result<Result<&'static str, u32>, u32> = Ok(Ok("hello"));\nassert_eq!(Ok("hello"), x.flatten());\n\nlet x: Result<Result<&'static str, u32>, u32> = Ok(Err(6));\nassert_eq!(Err(6), x.flatten());\n\nlet x: Result<Result<&'static str, u32>, u32> = Err(6);\nassert_eq!(Err(6), x.flatten());
\n

Flattening only removes one level of nesting at a time:

\n\n
#![feature(result_flattening)]\nlet x: Result<Result<Result<&'static str, u32>, u32>, u32> = Ok(Ok(Ok("hello")));\nassert_eq!(Ok(Ok("hello")), x.flatten());\nassert_eq!(Ok("hello"), x.flatten().flatten());
\n
",0,"ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.61.0 · source§

impl<T, E> Termination for Result<T, E>where\n T: Termination,\n E: Debug,

source§

fn report(self) -> ExitCode

Is called to get the representation of the value as status code.\nThis status code is returned to the operating system.
","Termination","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E, F> FromResidual<Yeet<E>> for Result<T, F>where\n F: From<E>,

source§

fn from_residual(_: Yeet<E>) -> Result<T, F>

🔬This is a nightly-only experimental API. (try_trait_v2)
Constructs the type from a compatible Residual type. Read more
","FromResidual>","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>where\n F: From<E>,

source§

fn from_residual(residual: Result<Infallible, E>) -> Result<T, F>

🔬This is a nightly-only experimental API. (try_trait_v2)
Constructs the type from a compatible Residual type. Read more
","FromResidual>","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E> Try for Result<T, E>

§

type Output = T

🔬This is a nightly-only experimental API. (try_trait_v2)
The type of the value produced by ? when not short-circuiting.
§

type Residual = Result<Infallible, E>

🔬This is a nightly-only experimental API. (try_trait_v2)
The type of the value passed to FromResidual::from_residual\nas part of ? when short-circuiting. Read more
source§

fn from_output(output: <Result<T, E> as Try>::Output) -> Result<T, E>

🔬This is a nightly-only experimental API. (try_trait_v2)
Constructs the type from its Output type. Read more
source§

fn branch(\n self\n) -> ControlFlow<<Result<T, E> as Try>::Residual, <Result<T, E> as Try>::Output>

🔬This is a nightly-only experimental API. (try_trait_v2)
Used in ? to decide whether the operator should produce a value\n(because this returned ControlFlow::Continue)\nor propagate a value back to the caller\n(because this returned ControlFlow::Break). Read more
","Try","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> StructuralEq for Result<T, E>

","StructuralEq","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> Eq for Result<T, E>where\n T: Eq,\n E: Eq,

","Eq","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<A, E, V> FromIterator<Result<A, E>> for Result<V, E>where\n V: FromIterator<A>,

source§

fn from_iter<I>(iter: I) -> Result<V, E>where\n I: IntoIterator<Item = Result<A, E>>,

Takes each element in the Iterator: if it is an Err, no further\nelements are taken, and the Err is returned. Should no Err occur, a\ncontainer with the values of each Result is returned.

\n

Here is an example which increments every integer in a vector,\nchecking for overflow:

\n\n
let v = vec![1, 2];\nlet res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|\n    x.checked_add(1).ok_or("Overflow!")\n).collect();\nassert_eq!(res, Ok(vec![2, 3]));
\n

Here is another example that tries to subtract one from another list\nof integers, this time checking for underflow:

\n\n
let v = vec![1, 2, 0];\nlet res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|\n    x.checked_sub(1).ok_or("Underflow!")\n).collect();\nassert_eq!(res, Err("Underflow!"));
\n

Here is a variation on the previous example, showing that no\nfurther elements are taken from iter after the first Err.

\n\n
let v = vec![3, 2, 1, 10];\nlet mut shared = 0;\nlet res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32| {\n    shared += x;\n    x.checked_sub(2).ok_or("Underflow!")\n}).collect();\nassert_eq!(res, Err("Underflow!"));\nassert_eq!(shared, 6);
\n

Since the third element caused an underflow, no further elements were taken,\nso the final value of shared is 6 (= 3 + 2 + 1), not 16.

\n
","FromIterator>","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> Ord for Result<T, E>where\n T: Ord,\n E: Ord,

source§

fn cmp(&self, other: &Result<T, E>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Selfwhere\n Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Selfwhere\n Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Selfwhere\n Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
","Ord","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> PartialEq for Result<T, E>where\n T: PartialEq,\n E: PartialEq,

source§

fn eq(&self, other: &Result<T, E>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> Clone for Result<T, E>where\n T: Clone,\n E: Clone,

source§

fn clone(&self) -> Result<T, E>

Returns a copy of the value. Read more
source§

fn clone_from(&mut self, source: &Result<T, E>)

Performs copy-assignment from source. Read more
","Clone","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> Hash for Result<T, E>where\n T: Hash,\n E: Hash,

source§

fn hash<__H>(&self, state: &mut __H)where\n __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)where\n H: Hasher,\n Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
","Hash","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> IntoIterator for Result<T, E>

source§

fn into_iter(self) -> IntoIter<T>

Returns a consuming iterator over the possibly contained value.

\n

The iterator yields one value if the result is Result::Ok, otherwise none.

\n
Examples
\n
let x: Result<u32, &str> = Ok(5);\nlet v: Vec<u32> = x.into_iter().collect();\nassert_eq!(v, [5]);\n\nlet x: Result<u32, &str> = Err("nothing!");\nlet v: Vec<u32> = x.into_iter().collect();\nassert_eq!(v, []);
\n
§

type Item = T

The type of the elements being iterated over.
§

type IntoIter = IntoIter<T>

Which kind of iterator are we turning this into?
","IntoIterator","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
source§

impl<T, E> Residual<T> for Result<Infallible, E>

§

type TryType = Result<T, E>

🔬This is a nightly-only experimental API. (try_trait_v2_residual)
The “return” type of this meta-function.
","Residual","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> StructuralPartialEq for Result<T, E>

","StructuralPartialEq","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.16.0 · source§

impl<T, U, E> Sum<Result<U, E>> for Result<T, E>where\n T: Sum<U>,

source§

fn sum<I>(iter: I) -> Result<T, E>where\n I: Iterator<Item = Result<U, E>>,

Takes each element in the Iterator: if it is an Err, no further\nelements are taken, and the Err is returned. Should no Err\noccur, the sum of all elements is returned.

\n
Examples
\n

This sums up every integer in a vector, rejecting the sum if a negative\nelement is encountered:

\n\n
let f = |&x: &i32| if x < 0 { Err("Negative element found") } else { Ok(x) };\nlet v = vec![1, 2];\nlet res: Result<i32, _> = v.iter().map(f).sum();\nassert_eq!(res, Ok(3));\nlet v = vec![1, -2];\nlet res: Result<i32, _> = v.iter().map(f).sum();\nassert_eq!(res, Err("Negative element found"));
\n
","Sum>","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> Debug for Result<T, E>where\n T: Debug,\n E: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Debug","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> PartialOrd for Result<T, E>where\n T: PartialOrd,\n E: PartialOrd,

source§

fn partial_cmp(&self, other: &Result<T, E>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <=\noperator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >=\noperator. Read more
","PartialOrd","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.0.0 · source§

impl<T, E> Copy for Result<T, E>where\n T: Copy,\n E: Copy,

","Copy","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"],["
1.16.0 · source§

impl<T, U, E> Product<Result<U, E>> for Result<T, E>where\n T: Product<U>,

source§

fn product<I>(iter: I) -> Result<T, E>where\n I: Iterator<Item = Result<U, E>>,

Takes each element in the Iterator: if it is an Err, no further\nelements are taken, and the Err is returned. Should no Err\noccur, the product of all elements is returned.

\n
Examples
\n

This multiplies each number in a vector of strings,\nif a string could not be parsed the operation returns Err:

\n\n
let nums = vec!["5", "10", "1", "2"];\nlet total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product();\nassert_eq!(total, Ok(100));\nlet nums = vec!["5", "10", "one", "2"];\nlet total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product();\nassert!(total.is_err());
\n
","Product>","ba2::fo4::Result","ba2::tes3::Result","ba2::tes4::Result"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file