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

List of all items

Structs

Enums

Traits

\ No newline at end of file diff --git a/ag_iso_stack/driver/address/struct.Address.html b/ag_iso_stack/driver/address/struct.Address.html new file mode 100644 index 0000000..9091c05 --- /dev/null +++ b/ag_iso_stack/driver/address/struct.Address.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/struct.Address.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/can_id/enum.Priority.html b/ag_iso_stack/driver/can_id/enum.Priority.html new file mode 100644 index 0000000..71dd93c --- /dev/null +++ b/ag_iso_stack/driver/can_id/enum.Priority.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/enum.Priority.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/can_id/enum.Type.html b/ag_iso_stack/driver/can_id/enum.Type.html new file mode 100644 index 0000000..4e4e268 --- /dev/null +++ b/ag_iso_stack/driver/can_id/enum.Type.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/enum.Type.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/can_id/struct.CanId.html b/ag_iso_stack/driver/can_id/struct.CanId.html new file mode 100644 index 0000000..8733b75 --- /dev/null +++ b/ag_iso_stack/driver/can_id/struct.CanId.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/struct.CanId.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/driver/enum.DriverCloseError.html b/ag_iso_stack/driver/driver/enum.DriverCloseError.html new file mode 100644 index 0000000..36e5bf8 --- /dev/null +++ b/ag_iso_stack/driver/driver/enum.DriverCloseError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/enum.DriverCloseError.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/driver/enum.DriverOpenError.html b/ag_iso_stack/driver/driver/enum.DriverOpenError.html new file mode 100644 index 0000000..0523331 --- /dev/null +++ b/ag_iso_stack/driver/driver/enum.DriverOpenError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/enum.DriverOpenError.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/driver/enum.DriverReadError.html b/ag_iso_stack/driver/driver/enum.DriverReadError.html new file mode 100644 index 0000000..63e450a --- /dev/null +++ b/ag_iso_stack/driver/driver/enum.DriverReadError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/enum.DriverReadError.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/driver/enum.DriverWriteError.html b/ag_iso_stack/driver/driver/enum.DriverWriteError.html new file mode 100644 index 0000000..03b56b0 --- /dev/null +++ b/ag_iso_stack/driver/driver/enum.DriverWriteError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/enum.DriverWriteError.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/driver/trait.Driver.html b/ag_iso_stack/driver/driver/trait.Driver.html new file mode 100644 index 0000000..43d5d20 --- /dev/null +++ b/ag_iso_stack/driver/driver/trait.Driver.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/trait.Driver.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/enum.DriverCloseError.html b/ag_iso_stack/driver/enum.DriverCloseError.html new file mode 100644 index 0000000..2f7fb50 --- /dev/null +++ b/ag_iso_stack/driver/enum.DriverCloseError.html @@ -0,0 +1,15 @@ +DriverCloseError in ag_iso_stack::driver - Rust
#[non_exhaustive]
pub enum DriverCloseError {}

Trait Implementations§

source§

impl Debug for DriverCloseError

source§

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

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

impl Display for DriverCloseError

source§

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

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

impl Error for DriverCloseError

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, demand: &mut Demand<'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§

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<E> Provider for Ewhere + E: Error + ?Sized,

source§

fn provide<'a>(&'a self, demand: &mut Demand<'a>)

🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. 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.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/enum.DriverOpenError.html b/ag_iso_stack/driver/enum.DriverOpenError.html new file mode 100644 index 0000000..a0f09a8 --- /dev/null +++ b/ag_iso_stack/driver/enum.DriverOpenError.html @@ -0,0 +1,18 @@ +DriverOpenError in ag_iso_stack::driver - Rust
#[non_exhaustive]
pub enum DriverOpenError { + IoError(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.
§

IoError(Error)

The driver failed to open with filesystem semantics

+

Trait Implementations§

source§

impl Debug for DriverOpenError

source§

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

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

impl Display for DriverOpenError

source§

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

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

impl Error for DriverOpenError

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, demand: &mut Demand<'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 DriverOpenError

source§

fn from(e: Error) -> DriverOpenError

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<E> Provider for Ewhere + E: Error + ?Sized,

source§

fn provide<'a>(&'a self, demand: &mut Demand<'a>)

🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. 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.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/enum.DriverReadError.html b/ag_iso_stack/driver/enum.DriverReadError.html new file mode 100644 index 0000000..ee54ddc --- /dev/null +++ b/ag_iso_stack/driver/enum.DriverReadError.html @@ -0,0 +1,24 @@ +DriverReadError in ag_iso_stack::driver - Rust
#[non_exhaustive]
pub enum DriverReadError { + NoFrameReady, + DriverClosed, + ErrorFrame(), + IoError(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.
§

NoFrameReady

There is no frame ready to be read

+
§

DriverClosed

The driver has been closed

+
§

ErrorFrame()

The driver received an error frame

+
§

IoError(Error)

The driver failed to read with filesystem semantics

+

Trait Implementations§

source§

impl Debug for DriverReadError

source§

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

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

impl Display for DriverReadError

source§

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

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

impl Error for DriverReadError

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, demand: &mut Demand<'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 DriverReadError

source§

fn from(e: Error) -> DriverReadError

Converts to this type from the input type.
source§

impl From<Error> for DriverReadError

source§

fn from(e: Error) -> DriverReadError

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<E> Provider for Ewhere + E: Error + ?Sized,

source§

fn provide<'a>(&'a self, demand: &mut Demand<'a>)

🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. 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.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/enum.DriverWriteError.html b/ag_iso_stack/driver/enum.DriverWriteError.html new file mode 100644 index 0000000..9591631 --- /dev/null +++ b/ag_iso_stack/driver/enum.DriverWriteError.html @@ -0,0 +1,24 @@ +DriverWriteError in ag_iso_stack::driver - Rust
#[non_exhaustive]
pub enum DriverWriteError { + NotReady, + DriverClosed, + BusError(), + IoError(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.
§

NotReady

The driver’s internal buffer is full, or the driver is otherwise busy

+
§

DriverClosed

The driver has been closed

+
§

BusError()

Some fault with the CAN bus

+
§

IoError(Error)

Some fault with filesystem semantics

+

Trait Implementations§

source§

impl Debug for DriverWriteError

source§

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

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

impl Display for DriverWriteError

source§

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

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

impl Error for DriverWriteError

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, demand: &mut Demand<'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 DriverWriteError

source§

fn from(e: Error) -> DriverWriteError

Converts to this type from the input type.
source§

impl From<Error> for DriverWriteError

source§

fn from(e: Error) -> DriverWriteError

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<E> Provider for Ewhere + E: Error + ?Sized,

source§

fn provide<'a>(&'a self, demand: &mut Demand<'a>)

🔬This is a nightly-only experimental API. (provide_any)
Data providers should implement this method to provide all values they are able to +provide by using demand. 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.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/enum.Priority.html b/ag_iso_stack/driver/enum.Priority.html new file mode 100644 index 0000000..3185d75 --- /dev/null +++ b/ag_iso_stack/driver/enum.Priority.html @@ -0,0 +1,29 @@ +Priority in ag_iso_stack::driver - Rust
pub enum Priority {
+    Zero,
+    One,
+    Two,
+    Three,
+    Four,
+    Five,
+    Six,
+    Seven,
+}

Variants§

§

Zero

You may also use Priority::Highest as an alias

+
§

One

§

Two

§

Three

§

Four

§

Five

§

Six

You may also use Priority::Default as an alias

+
§

Seven

You may also use Priority::Lowest as an alias

+

Implementations§

source§

impl Priority

source

pub const Highest: Priority = Priority::Zero

source

pub const Default: Priority = Priority::Six

source

pub const Lowest: Priority = Priority::Seven

Trait Implementations§

source§

impl Clone for Priority

source§

fn clone(&self) -> Priority

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 Priority

source§

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

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

impl From<u8> for Priority

source§

fn from(value: u8) -> Priority

Converts to this type from the input type.
source§

impl Hash for Priority

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

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
source§

impl PartialEq<Priority> for Priority

source§

fn eq(&self, other: &Priority) -> 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 Priority

source§

impl Eq for Priority

source§

impl StructuralEq for Priority

source§

impl StructuralPartialEq for Priority

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/enum.Type.html b/ag_iso_stack/driver/enum.Type.html new file mode 100644 index 0000000..4b43bc9 --- /dev/null +++ b/ag_iso_stack/driver/enum.Type.html @@ -0,0 +1,22 @@ +Type in ag_iso_stack::driver - Rust
pub enum Type {
+    Standard,
+    Extended,
+}

Variants§

§

Standard

11-bit CAN ID

+
§

Extended

29-bit CAN ID

+

Trait Implementations§

source§

impl Clone for Type

source§

fn clone(&self) -> Type

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 Type

source§

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

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

impl Hash for Type

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

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
source§

impl PartialEq<Type> for Type

source§

fn eq(&self, other: &Type) -> 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 Type

source§

impl Eq for Type

source§

impl StructuralEq for Type

source§

impl StructuralPartialEq for Type

Auto Trait Implementations§

§

impl RefUnwindSafe for Type

§

impl Send for Type

§

impl Sync for Type

§

impl Unpin for Type

§

impl UnwindSafe for Type

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/frame/struct.Channel.html b/ag_iso_stack/driver/frame/struct.Channel.html new file mode 100644 index 0000000..e39f5c6 --- /dev/null +++ b/ag_iso_stack/driver/frame/struct.Channel.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/struct.Channel.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/frame/struct.Frame.html b/ag_iso_stack/driver/frame/struct.Frame.html new file mode 100644 index 0000000..9d117ef --- /dev/null +++ b/ag_iso_stack/driver/frame/struct.Frame.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/struct.Frame.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/index.html b/ag_iso_stack/driver/index.html new file mode 100644 index 0000000..2a62637 --- /dev/null +++ b/ag_iso_stack/driver/index.html @@ -0,0 +1,7 @@ +ag_iso_stack::driver - Rust

Module ag_iso_stack::driver

source ·
Expand description

CAN Driver layer

+

This module defines:

+
    +
  1. An abstract Driver trait for different CAN drivers to implement
  2. +
  3. Frame, Pgn, Address, et al types
  4. +
+

Structs

Enums

Traits

  • Generic interface for CAN drivers
\ No newline at end of file diff --git a/ag_iso_stack/driver/pgn/struct.Pgn.html b/ag_iso_stack/driver/pgn/struct.Pgn.html new file mode 100644 index 0000000..a76ab0b --- /dev/null +++ b/ag_iso_stack/driver/pgn/struct.Pgn.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/struct.Pgn.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/sidebar-items.js b/ag_iso_stack/driver/sidebar-items.js new file mode 100644 index 0000000..4c469e1 --- /dev/null +++ b/ag_iso_stack/driver/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["DriverCloseError","DriverOpenError","DriverReadError","DriverWriteError","Priority","Type"],"struct":["Address","CanId","Channel","Frame","Pgn","SocketcanDriver"],"trait":["Driver"]}; \ No newline at end of file diff --git a/ag_iso_stack/driver/socketcan/struct.SocketcanDriver.html b/ag_iso_stack/driver/socketcan/struct.SocketcanDriver.html new file mode 100644 index 0000000..f94ffa5 --- /dev/null +++ b/ag_iso_stack/driver/socketcan/struct.SocketcanDriver.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../ag_iso_stack/driver/struct.SocketcanDriver.html...

+ + + \ No newline at end of file diff --git a/ag_iso_stack/driver/struct.Address.html b/ag_iso_stack/driver/struct.Address.html new file mode 100644 index 0000000..2e67753 --- /dev/null +++ b/ag_iso_stack/driver/struct.Address.html @@ -0,0 +1,20 @@ +Address in ag_iso_stack::driver - Rust
#[repr(transparent)]
pub struct Address(pub u8);

Tuple Fields§

§0: u8

Implementations§

source§

impl Address

source

pub const GLOBAL: Address = _

Address representing broadcasts for destination specific PGNs

+
source

pub const BROADCAST: Address = _

Alias for the global address

+
source

pub const NULL: Address = _

The null address is used by ECUs without an address such as during address claiming

+

Trait Implementations§

source§

impl Clone for Address

source§

fn clone(&self) -> Address

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 Address

source§

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

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

impl Hash for Address

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

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
source§

impl PartialEq<Address> for Address

source§

fn eq(&self, other: &Address) -> 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 Address

source§

impl Eq for Address

source§

impl StructuralEq for Address

source§

impl StructuralPartialEq for Address

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/struct.CanId.html b/ag_iso_stack/driver/struct.CanId.html new file mode 100644 index 0000000..f860f1d --- /dev/null +++ b/ag_iso_stack/driver/struct.CanId.html @@ -0,0 +1,41 @@ +CanId in ag_iso_stack::driver - Rust

Struct ag_iso_stack::driver::CanId

source ·
#[repr(transparent)]
pub struct CanId(_);

Implementations§

source§

impl CanId

source

pub fn new(raw: u32, type_: Type) -> Self

source

pub fn try_encode( + parameter_group_number: Pgn, + source_address: Address, + destination_address: Address, + priority: Priority +) -> Result<CanId, EncodingError>

Encodes a new extended ID using the discrete parts of an identifier

+
source

pub unsafe fn encode_unchecked( + parameter_group_number: Pgn, + source_address: Address, + destination_address: Address, + priority: Priority +) -> CanId

Encodes a new extended ID using the discrete parts of an identifier but won’t validate +your combination of PGN and destination address.

+
Safety
+

Calling this without validating your PGN and destination address combination may result in your PGN field +getting trashed. Specifically, the risk is when you are using a broadcast PGN but supply a non-0xFF +destination address.

+
source

pub fn raw(&self) -> u32

Get the raw value of the CAN ID

+
source

pub fn type_(&self) -> Type

Get the type of the ID (standard or extended)

+
source

pub fn priority(&self) -> Priority

Get the priority of the ID

+
source

pub fn source_address(&self) -> Address

Get the source address of the ID

+
source

pub fn pgn(&self) -> Pgn

Get the ID’s PGN

+

In the case the the ID is a standard 11-bit ID, a NULL PGN will be returned.

+
source

pub fn destination_address(&self) -> Address

Get the destination address for this CAN ID, if it’s a destination-specific PGN

+

Trait Implementations§

source§

impl Clone for CanId

source§

fn clone(&self) -> CanId

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 CanId

source§

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

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

impl Default for CanId

source§

fn default() -> CanId

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

impl Hash for CanId

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

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
source§

impl PartialEq<CanId> for CanId

source§

fn eq(&self, other: &CanId) -> 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 CanId

source§

impl Eq for CanId

source§

impl StructuralEq for CanId

source§

impl StructuralPartialEq for CanId

Auto Trait Implementations§

§

impl RefUnwindSafe for CanId

§

impl Send for CanId

§

impl Sync for CanId

§

impl Unpin for CanId

§

impl UnwindSafe for CanId

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/struct.Channel.html b/ag_iso_stack/driver/struct.Channel.html new file mode 100644 index 0000000..0cf1487 --- /dev/null +++ b/ag_iso_stack/driver/struct.Channel.html @@ -0,0 +1,12 @@ +Channel in ag_iso_stack::driver - Rust
#[repr(transparent)]
pub struct Channel(_);

Trait Implementations§

source§

impl Debug for Channel

source§

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

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

impl Default for Channel

source§

fn default() -> Channel

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/struct.Frame.html b/ag_iso_stack/driver/struct.Frame.html new file mode 100644 index 0000000..1407850 --- /dev/null +++ b/ag_iso_stack/driver/struct.Frame.html @@ -0,0 +1,19 @@ +Frame in ag_iso_stack::driver - Rust

Struct ag_iso_stack::driver::Frame

source ·
pub struct Frame {
+    pub timestamp: Duration,
+    pub id: CanId,
+    pub channel: Channel,
+    pub data: [u8; 8],
+    pub data_length: u8,
+    pub extended: bool,
+}

Fields§

§timestamp: Duration§id: CanId§channel: Channel§data: [u8; 8]§data_length: u8§extended: bool

Trait Implementations§

source§

impl Debug for Frame

source§

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

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

impl Default for Frame

source§

fn default() -> Frame

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

impl From<&Frame> for CanDataFrame

source§

fn from(f: &InternalFrame) -> CanDataFrame

Converts to this type from the input type.

Auto Trait Implementations§

§

impl RefUnwindSafe for Frame

§

impl Send for Frame

§

impl Sync for Frame

§

impl Unpin for Frame

§

impl UnwindSafe for Frame

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/struct.Pgn.html b/ag_iso_stack/driver/struct.Pgn.html new file mode 100644 index 0000000..f357d39 --- /dev/null +++ b/ag_iso_stack/driver/struct.Pgn.html @@ -0,0 +1,18 @@ +Pgn in ag_iso_stack::driver - Rust

Struct ag_iso_stack::driver::Pgn

source ·
#[repr(transparent)]
pub struct Pgn(_);

Implementations§

source§

impl Pgn

source

pub const NULL: Pgn = _

A fake PGN used to denote a PGN that does not exist

+
source

pub fn from_id(can_id: u32) -> Self

source

pub fn from_raw(pgn: u32) -> Self

source

pub fn is_broadcast(&self) -> bool

source

pub fn is_destination_specific(&self) -> bool

source

pub fn is_proprietary(&self) -> bool

source

pub fn raw(&self) -> u32

source

pub fn pdu_specific(&self) -> u8

source

pub fn pdu_format(&self) -> u8

source

pub fn data_page(&self) -> u8

source

pub fn extended_data_page(&self) -> u8

Trait Implementations§

source§

impl Clone for Pgn

source§

fn clone(&self) -> Pgn

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 Pgn

source§

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

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

impl Hash for Pgn

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

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
source§

impl PartialEq<Pgn> for Pgn

source§

fn eq(&self, other: &Pgn) -> 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 Pgn

source§

impl Eq for Pgn

source§

impl StructuralEq for Pgn

source§

impl StructuralPartialEq for Pgn

Auto Trait Implementations§

§

impl RefUnwindSafe for Pgn

§

impl Send for Pgn

§

impl Sync for Pgn

§

impl Unpin for Pgn

§

impl UnwindSafe for Pgn

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/struct.SocketcanDriver.html b/ag_iso_stack/driver/struct.SocketcanDriver.html new file mode 100644 index 0000000..2f95957 --- /dev/null +++ b/ag_iso_stack/driver/struct.SocketcanDriver.html @@ -0,0 +1,24 @@ +SocketcanDriver in ag_iso_stack::driver - Rust
pub struct SocketcanDriver { /* private fields */ }
Expand description

A Linux socketcan Driver

+

Enabled with the optional socketcan feature

+

Implementations§

source§

impl SocketcanDriver

source

pub fn new_by_name(if_name: &str) -> Self

Create a socketcan driver with the given interface name. E.g., can0, or vcan1

+
source

pub fn new_by_index(if_index: u32) -> Self

Create a socketcan driver with the given interface index

+

Trait Implementations§

source§

impl Driver for SocketcanDriver

source§

fn read_nonblocking( + &mut self, + frame: &mut InternalFrame +) -> Result<(), DriverReadError>

Read a frame from the driver, if possible

+

The timestamp on the frame is the duration since open was last called.

+
source§

fn is_valid(&self) -> bool

Determine whether the driver is connected and healthy
source§

fn open(&mut self) -> Result<(), DriverOpenError>

Open the driver Read more
source§

fn close(&mut self) -> Result<(), DriverCloseError>

Close the driver Read more
source§

fn write_nonblocking( + &mut self, + frame: &InternalFrame +) -> Result<(), DriverWriteError>

Write a Frame to the driver, if possible 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.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/driver/trait.Driver.html b/ag_iso_stack/driver/trait.Driver.html new file mode 100644 index 0000000..5f680cf --- /dev/null +++ b/ag_iso_stack/driver/trait.Driver.html @@ -0,0 +1,34 @@ +Driver in ag_iso_stack::driver - Rust
pub trait Driver {
+    // Required methods
+    fn is_valid(&self) -> bool;
+    fn open(&mut self) -> Result<(), DriverOpenError>;
+    fn close(&mut self) -> Result<(), DriverCloseError>;
+    fn read_nonblocking(
+        &mut self,
+        frame: &mut Frame
+    ) -> Result<(), DriverReadError>;
+    fn write_nonblocking(
+        &mut self,
+        frame: &Frame
+    ) -> Result<(), DriverWriteError>;
+}
Expand description

Generic interface for CAN drivers

+

This layer is meant to abstract the hardware, and should not do its own queuing/buffering.

+

This trait does not define how to construct and configure a driver, as the details are likely +to differ from driver to driver.

+

Required Methods§

source

fn is_valid(&self) -> bool

Determine whether the driver is connected and healthy

+
source

fn open(&mut self) -> Result<(), DriverOpenError>

Open the driver

+

It is expected you must open the driver after creating it

+
source

fn close(&mut self) -> Result<(), DriverCloseError>

Close the driver

+

It is not necessary to close the driver before dropping it

+
source

fn read_nonblocking(&mut self, frame: &mut Frame) -> Result<(), DriverReadError>

Read a Frame from the driver, if possible

+

This is a non-blocking read. If there is no frame ready to read, this function will return +DriverReadError::NoFrameReady.

+

An out-parameter is used, so that the user can choose whether to construct a new frame for +each call, or to re-use memory.

+
source

fn write_nonblocking(&mut self, frame: &Frame) -> Result<(), DriverWriteError>

Write a Frame to the driver, if possible

+

This is a non-blocking write. If the frame cannot be written because the driver’s +queue/buffer is full (for drivers like socketcan that do internal buffering), or if +it’s otherwise busy, this function will return DriverWriteError::NotReady.

+

For drivers that defer to some other implementation (Peak, Socketcan), it’s likely that the +given frame is copied before being written.

+

Implementors§

\ No newline at end of file diff --git a/ag_iso_stack/index.html b/ag_iso_stack/index.html new file mode 100644 index 0000000..847c8bf --- /dev/null +++ b/ag_iso_stack/index.html @@ -0,0 +1 @@ +ag_iso_stack - Rust

Crate ag_iso_stack

source ·

Modules

\ No newline at end of file diff --git a/ag_iso_stack/network_management/can_message/index.html b/ag_iso_stack/network_management/can_message/index.html new file mode 100644 index 0000000..79b7fbb --- /dev/null +++ b/ag_iso_stack/network_management/can_message/index.html @@ -0,0 +1 @@ +ag_iso_stack::network_management::can_message - Rust

Structs

\ No newline at end of file diff --git a/ag_iso_stack/network_management/can_message/sidebar-items.js b/ag_iso_stack/network_management/can_message/sidebar-items.js new file mode 100644 index 0000000..87d4537 --- /dev/null +++ b/ag_iso_stack/network_management/can_message/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["CANMessage"]}; \ No newline at end of file diff --git a/ag_iso_stack/network_management/can_message/struct.CANMessage.html b/ag_iso_stack/network_management/can_message/struct.CANMessage.html new file mode 100644 index 0000000..39839fb --- /dev/null +++ b/ag_iso_stack/network_management/can_message/struct.CANMessage.html @@ -0,0 +1,12 @@ +CANMessage in ag_iso_stack::network_management::can_message - Rust
pub struct CANMessage { /* private fields */ }

Implementations§

source§

impl CANMessage

source

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

source

pub fn get_identifier(&self) -> CanId

source

pub fn get_source_name(&self) -> NAME

source

pub fn get_destination_name(&self) -> NAME

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/common_parameter_group_numbers/enum.CommonParameterGroupNumbers.html b/ag_iso_stack/network_management/common_parameter_group_numbers/enum.CommonParameterGroupNumbers.html new file mode 100644 index 0000000..738888c --- /dev/null +++ b/ag_iso_stack/network_management/common_parameter_group_numbers/enum.CommonParameterGroupNumbers.html @@ -0,0 +1,73 @@ +CommonParameterGroupNumbers in ag_iso_stack::network_management::common_parameter_group_numbers - Rust
pub enum CommonParameterGroupNumbers {
+
Show 57 variants TractorImplementManagementServerToTimClient, + TractorImplementManagementClientToTimServer, + AuthenticationClientToAuthenticationServer, + AuthenticationServerToAuthenticationClient, + NameManagement, + GuidanceMachineStatus, + GuidanceSystemCommand, + ExtendedTransportProtocolData, + ExtendedTransportProtocolCommand, + RequestForRepetitionRate, + BinaryDataTransfer, + MemoryAccessResponse, + MemoryAccessRequest, + StopStartBroadcast, + VirtualTerminalToNode, + NodeToVirtualTerminal, + Acknowledgement, + ParameterGroupNumberRequest, + TransportProtocolData, + TransportProtocolCommand, + AddressClaim, + ProprietaryA, + ElectronicEngineController2, + ElectronicEngineController1, + HeartbeatMessage, + ProductIdentification, + ControlFunctionFunctionalities, + DiagnosticProtocol, + IsobusComplianceCertificationMessage, + EcuIdentificationInformation, + WorkingSetMaster, + ResponseForRepetitionRate, + MaintainPower, + WheelBasedSpeedAndDistance, + GroundBasedSpeedAndDistance, + ActiveDiagnosticTroubleCodes, + PreviouslyActiveDiagnosticTroubleCodes, + DiagnosticDataClearResetOfPreviouslyActiveDtcs, + FreezeFrameParameters, + DiagnosticDataClearResetForActiveDtcs, + CommandedAddress, + SoftwareIdentification, + TimeDate, + EngineTemperature1, + CruiseControlVehicleSpeed1, + IntakeExhaustConditions1, + NmeaAttitude, + NmeaCogSogRapidUpdate, + NmeaPositionDeltaHighPrecisionRapidUpdate, + NmeaAltitudeDeltaHighPrecisionRapidUpdate, + NmeaGnssPositionData, + NmeaTimeDate, + NmeaGnssDops, + NmeaGnssSatsInView, + NmeaGnssPseudoRangeNoiseStatistics, + NmeaGnssPseudoRangeErrorStatistics, + AllowAll, +
}

Variants§

§

TractorImplementManagementServerToTimClient

§

TractorImplementManagementClientToTimServer

§

AuthenticationClientToAuthenticationServer

§

AuthenticationServerToAuthenticationClient

§

NameManagement

§

GuidanceMachineStatus

§

GuidanceSystemCommand

§

ExtendedTransportProtocolData

§

ExtendedTransportProtocolCommand

§

RequestForRepetitionRate

§

BinaryDataTransfer

§

MemoryAccessResponse

§

MemoryAccessRequest

§

StopStartBroadcast

§

VirtualTerminalToNode

§

NodeToVirtualTerminal

§

Acknowledgement

§

ParameterGroupNumberRequest

§

TransportProtocolData

§

TransportProtocolCommand

§

AddressClaim

§

ProprietaryA

§

ElectronicEngineController2

§

ElectronicEngineController1

§

HeartbeatMessage

§

ProductIdentification

§

ControlFunctionFunctionalities

§

DiagnosticProtocol

§

IsobusComplianceCertificationMessage

§

EcuIdentificationInformation

§

WorkingSetMaster

§

ResponseForRepetitionRate

§

MaintainPower

§

WheelBasedSpeedAndDistance

§

GroundBasedSpeedAndDistance

§

ActiveDiagnosticTroubleCodes

§

PreviouslyActiveDiagnosticTroubleCodes

§

DiagnosticDataClearResetOfPreviouslyActiveDtcs

§

FreezeFrameParameters

§

DiagnosticDataClearResetForActiveDtcs

§

CommandedAddress

§

SoftwareIdentification

§

TimeDate

§

EngineTemperature1

§

CruiseControlVehicleSpeed1

§

IntakeExhaustConditions1

§

NmeaAttitude

§

NmeaCogSogRapidUpdate

§

NmeaPositionDeltaHighPrecisionRapidUpdate

§

NmeaAltitudeDeltaHighPrecisionRapidUpdate

§

NmeaGnssPositionData

§

NmeaTimeDate

§

NmeaGnssDops

§

NmeaGnssSatsInView

§

NmeaGnssPseudoRangeNoiseStatistics

§

NmeaGnssPseudoRangeErrorStatistics

§

AllowAll

Trait Implementations§

source§

impl Clone for CommonParameterGroupNumbers

source§

fn clone(&self) -> CommonParameterGroupNumbers

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 CommonParameterGroupNumbers

source§

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

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

impl PartialEq<CommonParameterGroupNumbers> for CommonParameterGroupNumbers

source§

fn eq(&self, other: &CommonParameterGroupNumbers) -> 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 CommonParameterGroupNumbers

source§

impl Eq for CommonParameterGroupNumbers

source§

impl StructuralEq for CommonParameterGroupNumbers

source§

impl StructuralPartialEq for CommonParameterGroupNumbers

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/common_parameter_group_numbers/index.html b/ag_iso_stack/network_management/common_parameter_group_numbers/index.html new file mode 100644 index 0000000..50100eb --- /dev/null +++ b/ag_iso_stack/network_management/common_parameter_group_numbers/index.html @@ -0,0 +1 @@ +ag_iso_stack::network_management::common_parameter_group_numbers - Rust

Enums

\ No newline at end of file diff --git a/ag_iso_stack/network_management/common_parameter_group_numbers/sidebar-items.js b/ag_iso_stack/network_management/common_parameter_group_numbers/sidebar-items.js new file mode 100644 index 0000000..98ab236 --- /dev/null +++ b/ag_iso_stack/network_management/common_parameter_group_numbers/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CommonParameterGroupNumbers"]}; \ No newline at end of file diff --git a/ag_iso_stack/network_management/control_function/enum.AddressClaimingState.html b/ag_iso_stack/network_management/control_function/enum.AddressClaimingState.html new file mode 100644 index 0000000..8bf86a3 --- /dev/null +++ b/ag_iso_stack/network_management/control_function/enum.AddressClaimingState.html @@ -0,0 +1,36 @@ +AddressClaimingState in ag_iso_stack::network_management::control_function - Rust
pub enum AddressClaimingState {
+    None,
+    WaitForClaim,
+    SendRequestForClaim,
+    WaitForRequestContentionPeriod,
+    SendPreferredAddressClaim,
+    ContendForPreferredAddress,
+    SendArbitraryAddressClaim,
+    SendReclaimAddressOnRequest,
+    UnableToClaim,
+    AddressClaimingComplete,
+}

Variants§

§

None

Address claiming is uninitialized

+
§

WaitForClaim

State machine is waiting for the random delay time

+
§

SendRequestForClaim

State machine is sending the request for address claim

+
§

WaitForRequestContentionPeriod

State machine is waiting for the address claim contention period

+
§

SendPreferredAddressClaim

State machine is claiming the preferred address

+
§

ContendForPreferredAddress

State machine is contending the preferred address

+
§

SendArbitraryAddressClaim

State machine is claiming an address

+
§

SendReclaimAddressOnRequest

An ECU requested address claim, inform the bus of our current address

+
§

UnableToClaim

State machine could not claim an address

+
§

AddressClaimingComplete

Address claiming is complete and we have an address

+

Trait Implementations§

source§

impl Clone for AddressClaimingState

source§

fn clone(&self) -> AddressClaimingState

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 Default for AddressClaimingState

source§

fn default() -> Self

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

impl PartialEq<AddressClaimingState> for AddressClaimingState

source§

fn eq(&self, other: &AddressClaimingState) -> 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 AddressClaimingState

source§

impl Eq for AddressClaimingState

source§

impl StructuralEq for AddressClaimingState

source§

impl StructuralPartialEq for AddressClaimingState

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/control_function/enum.ControlFunction.html b/ag_iso_stack/network_management/control_function/enum.ControlFunction.html new file mode 100644 index 0000000..90e40a0 --- /dev/null +++ b/ag_iso_stack/network_management/control_function/enum.ControlFunction.html @@ -0,0 +1,24 @@ +ControlFunction in ag_iso_stack::network_management::control_function - Rust
pub enum ControlFunction {
+    Internal {
+        address_claim_data: AddressClaimingData,
+    },
+    External {
+        name: NAME,
+    },
+}

Variants§

§

Internal

Fields

§address_claim_data: AddressClaimingData
§

External

Fields

§name: NAME

Implementations§

source§

impl ControlFunction

source

pub fn new_internal_control_function( + name: NAME, + preferred_address: Address, + enabled: bool, + network: &mut NetworkManager +) -> Rc<RefCell<Self>>

source

pub fn get_name(&self) -> NAME

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/control_function/index.html b/ag_iso_stack/network_management/control_function/index.html new file mode 100644 index 0000000..89b0645 --- /dev/null +++ b/ag_iso_stack/network_management/control_function/index.html @@ -0,0 +1 @@ +ag_iso_stack::network_management::control_function - Rust

Structs

Enums

\ No newline at end of file diff --git a/ag_iso_stack/network_management/control_function/sidebar-items.js b/ag_iso_stack/network_management/control_function/sidebar-items.js new file mode 100644 index 0000000..fd8602a --- /dev/null +++ b/ag_iso_stack/network_management/control_function/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["AddressClaimingState","ControlFunction"],"struct":["AddressClaimingData"]}; \ No newline at end of file diff --git a/ag_iso_stack/network_management/control_function/struct.AddressClaimingData.html b/ag_iso_stack/network_management/control_function/struct.AddressClaimingData.html new file mode 100644 index 0000000..eb1ff66 --- /dev/null +++ b/ag_iso_stack/network_management/control_function/struct.AddressClaimingData.html @@ -0,0 +1,16 @@ +AddressClaimingData in ag_iso_stack::network_management::control_function - Rust
pub struct AddressClaimingData { /* private fields */ }

Implementations§

source§

impl AddressClaimingData

source

pub fn new( + name: NAME, + preferred_address: Address, + enabled: bool +) -> AddressClaimingData

source

pub fn get_enabled(&self) -> bool

source

pub fn set_enabled(&mut self, enable: bool)

source

pub fn get_preferred_address(&self) -> Address

source

pub fn get_state(&self) -> AddressClaimingState

source

pub fn get_name(&self) -> NAME

source

pub fn set_name(&mut self, new_name: NAME)

source

pub fn get_timestamp(&self) -> Option<Instant>

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

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

Modules

\ No newline at end of file diff --git a/ag_iso_stack/network_management/name/enum.NameField.html b/ag_iso_stack/network_management/name/enum.NameField.html new file mode 100644 index 0000000..7680418 --- /dev/null +++ b/ag_iso_stack/network_management/name/enum.NameField.html @@ -0,0 +1,27 @@ +NameField in ag_iso_stack::network_management::name - Rust
pub enum NameField {
+    IdentityNumber(u32),
+    ShortIdentityNumber(u16),
+    ExtendedIdentityNumber(u8),
+    ManufacturerCode(u16),
+    EcuInstance(u8),
+    FunctionInstance(u8),
+    Function(u8),
+    DeviceClass(u8),
+    DeviceClassInstance(u8),
+    IndustryGroup(u8),
+    SelfConfigurableAddress(bool),
+}

Variants§

§

IdentityNumber(u32)

§

ShortIdentityNumber(u16)

§

ExtendedIdentityNumber(u8)

§

ManufacturerCode(u16)

§

EcuInstance(u8)

§

FunctionInstance(u8)

§

Function(u8)

§

DeviceClass(u8)

§

DeviceClassInstance(u8)

§

IndustryGroup(u8)

§

SelfConfigurableAddress(bool)

Trait Implementations§

source§

impl Clone for NameField

source§

fn clone(&self) -> NameField

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 PartialEq<NameField> for NameField

source§

fn eq(&self, other: &NameField) -> 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 NameField

source§

impl Eq for NameField

source§

impl StructuralEq for NameField

source§

impl StructuralPartialEq for NameField

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/name/index.html b/ag_iso_stack/network_management/name/index.html new file mode 100644 index 0000000..b08300a --- /dev/null +++ b/ag_iso_stack/network_management/name/index.html @@ -0,0 +1 @@ +ag_iso_stack::network_management::name - Rust

Structs

Enums

\ No newline at end of file diff --git a/ag_iso_stack/network_management/name/sidebar-items.js b/ag_iso_stack/network_management/name/sidebar-items.js new file mode 100644 index 0000000..3c71618 --- /dev/null +++ b/ag_iso_stack/network_management/name/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["NameField"],"struct":["NAME","NameBuilder"]}; \ No newline at end of file diff --git a/ag_iso_stack/network_management/name/struct.NAME.html b/ag_iso_stack/network_management/name/struct.NAME.html new file mode 100644 index 0000000..e9362a1 --- /dev/null +++ b/ag_iso_stack/network_management/name/struct.NAME.html @@ -0,0 +1,15 @@ +NAME in ag_iso_stack::network_management::name - Rust
pub struct NAME { /* private fields */ }

Implementations§

source§

impl NAME

source

pub fn new(raw_name: u64) -> Self

source

pub fn builder() -> NameBuilder

source

pub fn has_field_value(&self, field_value: NameField) -> bool

source

pub fn has_field_values(&self, name_fields: &[NameField]) -> bool

source

pub fn get_device_class(&self) -> u8

source

pub fn set_device_class(&mut self, device_class: u8)

source

pub fn get_device_class_instance(&self) -> u8

source

pub fn set_device_class_instance(&mut self, device_class_instance: u8)

source

pub fn get_ecu_instance(&self) -> u8

source

pub fn set_ecu_instance(&mut self, ecu_instance: u8)

source

pub fn get_extended_identity_number(&self) -> u8

source

pub fn set_extended_identity_number(&mut self, extended_identity_number: u8)

source

pub fn get_function(&self) -> u8

source

pub fn set_function(&mut self, function: u8)

source

pub fn get_function_instance(&self) -> u8

source

pub fn set_function_instance(&mut self, function: u8)

source

pub fn get_identity_number(&self) -> u32

source

pub fn set_identity_number(&mut self, identity_number: u32)

source

pub fn get_industry_group(&self) -> u8

source

pub fn set_industry_group(&mut self, industry_group: u8)

source

pub fn get_manufacturer_code(&self) -> u16

source

pub fn set_manufacturer_code(&mut self, manufacturer_code: u16)

source

pub fn get_self_configurable_address(&self) -> bool

source

pub fn set_self_configurable_address(&mut self, self_configurable_address: bool)

source

pub fn get_short_identity_number(&self) -> u16

source

pub fn set_short_identity_number(&mut self, short_identity_number: u16)

Trait Implementations§

source§

impl Clone for NAME

source§

fn clone(&self) -> NAME

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 Default for NAME

source§

fn default() -> Self

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

impl From<NAME> for NameBuilder

source§

fn from(value: NAME) -> Self

Converts to this type from the input type.
source§

impl From<NAME> for u64

source§

fn from(name: NAME) -> Self

Converts to this type from the input type.
source§

impl PartialEq<NAME> for NAME

source§

fn eq(&self, other: &NAME) -> 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 NAME

source§

impl StructuralPartialEq for NAME

Auto Trait Implementations§

§

impl RefUnwindSafe for NAME

§

impl Send for NAME

§

impl Sync for NAME

§

impl Unpin for NAME

§

impl UnwindSafe for NAME

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/name/struct.NameBuilder.html b/ag_iso_stack/network_management/name/struct.NameBuilder.html new file mode 100644 index 0000000..254b116 --- /dev/null +++ b/ag_iso_stack/network_management/name/struct.NameBuilder.html @@ -0,0 +1,18 @@ +NameBuilder in ag_iso_stack::network_management::name - Rust
pub struct NameBuilder { /* private fields */ }

Implementations§

source§

impl NameBuilder

source

pub fn new() -> NameBuilder

source

pub fn build(&self) -> NAME

source

pub fn self_configurable_address( + &mut self, + value: impl Into<bool> +) -> &mut NameBuilder

source

pub fn industry_group(&mut self, value: impl Into<u8>) -> &mut NameBuilder

source

pub fn device_class_instance( + &mut self, + value: impl Into<u8> +) -> &mut NameBuilder

source

pub fn device_class(&mut self, value: impl Into<u8>) -> &mut NameBuilder

source

pub fn function_code(&mut self, value: impl Into<u8>) -> &mut NameBuilder

source

pub fn function_instance(&mut self, value: impl Into<u8>) -> &mut NameBuilder

source

pub fn ecu_instance(&mut self, value: impl Into<u8>) -> &mut NameBuilder

source

pub fn manufacturer_code(&mut self, value: impl Into<u16>) -> &mut NameBuilder

source

pub fn identity_number(&mut self, value: impl Into<u32>) -> &mut NameBuilder

Trait Implementations§

source§

impl Default for NameBuilder

source§

fn default() -> NameBuilder

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

impl From<NAME> for NameBuilder

source§

fn from(value: NAME) -> 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.
§

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/network_manager/enum.CANTransmitState.html b/ag_iso_stack/network_management/network_manager/enum.CANTransmitState.html new file mode 100644 index 0000000..46d928f --- /dev/null +++ b/ag_iso_stack/network_management/network_manager/enum.CANTransmitState.html @@ -0,0 +1,18 @@ +CANTransmitState in ag_iso_stack::network_management::network_manager - Rust
pub enum CANTransmitState {
+    Success,
+    Fail,
+}

Variants§

§

Success

Used to describe that a CAN message was accepted by the CAN stack to be sent

+
§

Fail

Used to describe that a CAN message was not accepted by the stack and will not be sent

+

Trait Implementations§

source§

impl Clone for CANTransmitState

source§

fn clone(&self) -> CANTransmitState

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 CANTransmitState

source§

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

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

impl Copy for CANTransmitState

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/network_manager/index.html b/ag_iso_stack/network_management/network_manager/index.html new file mode 100644 index 0000000..44ae156 --- /dev/null +++ b/ag_iso_stack/network_management/network_manager/index.html @@ -0,0 +1 @@ +ag_iso_stack::network_management::network_manager - Rust

Structs

Enums

\ No newline at end of file diff --git a/ag_iso_stack/network_management/network_manager/sidebar-items.js b/ag_iso_stack/network_management/network_manager/sidebar-items.js new file mode 100644 index 0000000..1eb8916 --- /dev/null +++ b/ag_iso_stack/network_management/network_manager/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CANTransmitState"],"struct":["NetworkManager"]}; \ No newline at end of file diff --git a/ag_iso_stack/network_management/network_manager/struct.NetworkManager.html b/ag_iso_stack/network_management/network_manager/struct.NetworkManager.html new file mode 100644 index 0000000..14bcdf2 --- /dev/null +++ b/ag_iso_stack/network_management/network_manager/struct.NetworkManager.html @@ -0,0 +1,22 @@ +NetworkManager in ag_iso_stack::network_management::network_manager - Rust
pub struct NetworkManager { /* private fields */ }

Implementations§

source§

impl NetworkManager

source

pub fn new() -> Self

source

pub fn get_control_function_by_address( + &self, + address: Address +) -> &Option<Rc<RefCell<ControlFunction>>>

source

pub fn get_control_function_address_by_name(&self, name: NAME) -> Address

source

pub fn send_can_message( + &mut self, + parameter_group_number: Pgn, + data: &[u8], + source: Rc<RefCell<ControlFunction>>, + destination: Rc<RefCell<ControlFunction>>, + priority: Priority +) -> CANTransmitState

source

pub fn update(self)

Trait Implementations§

source§

impl Default for NetworkManager

source§

fn default() -> Self

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

impl<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/ag_iso_stack/network_management/sidebar-items.js b/ag_iso_stack/network_management/sidebar-items.js new file mode 100644 index 0000000..f6ca72c --- /dev/null +++ b/ag_iso_stack/network_management/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["can_message","common_parameter_group_numbers","control_function","name","network_manager"]}; \ No newline at end of file diff --git a/ag_iso_stack/sidebar-items.js b/ag_iso_stack/sidebar-items.js new file mode 100644 index 0000000..c747e74 --- /dev/null +++ b/ag_iso_stack/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["driver","network_management"]}; \ No newline at end of file diff --git a/crates.js b/crates.js new file mode 100644 index 0000000..3161db9 --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["ag_iso_stack"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 0000000..31944fc --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Rustdoc help

Rustdoc help

Back
\ No newline at end of file diff --git a/implementors/ag_iso_stack/driver/driver/trait.Driver.js b/implementors/ag_iso_stack/driver/driver/trait.Driver.js new file mode 100644 index 0000000..3ebcdce --- /dev/null +++ b/implementors/ag_iso_stack/driver/driver/trait.Driver.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/clone/trait.Clone.js b/implementors/core/clone/trait.Clone.js new file mode 100644 index 0000000..78f2436 --- /dev/null +++ b/implementors/core/clone/trait.Clone.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Clone for AddressClaimingState"],["impl Clone for CommonParameterGroupNumbers"],["impl Clone for CANTransmitState"],["impl Clone for Address"],["impl Clone for Priority"],["impl Clone for NAME"],["impl Clone for Type"],["impl Clone for NameField"],["impl Clone for CanId"],["impl Clone for Pgn"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.Eq.js b/implementors/core/cmp/trait.Eq.js new file mode 100644 index 0000000..5c72987 --- /dev/null +++ b/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Eq for NameField"],["impl Eq for Type"],["impl Eq for CanId"],["impl Eq for AddressClaimingState"],["impl Eq for Priority"],["impl Eq for Address"],["impl Eq for CommonParameterGroupNumbers"],["impl Eq for Pgn"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/cmp/trait.PartialEq.js b/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 0000000..264d2f7 --- /dev/null +++ b/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl PartialEq<NAME> for NAME"],["impl PartialEq<Priority> for Priority"],["impl PartialEq<NameField> for NameField"],["impl PartialEq<Pgn> for Pgn"],["impl PartialEq<Address> for Address"],["impl PartialEq<AddressClaimingState> for AddressClaimingState"],["impl PartialEq<CanId> for CanId"],["impl PartialEq<Type> for Type"],["impl PartialEq<CommonParameterGroupNumbers> for CommonParameterGroupNumbers"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/convert/trait.From.js b/implementors/core/convert/trait.From.js new file mode 100644 index 0000000..04c71a6 --- /dev/null +++ b/implementors/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl From<NAME> for NameBuilder"],["impl From<Error> for DriverWriteError"],["impl From<NAME> for u64"],["impl From<Error> for DriverReadError"],["impl From<Error> for DriverOpenError"],["impl From<Error> for DriverWriteError"],["impl From<Error> for DriverReadError"],["impl From<u8> for Priority"],["impl From<&Frame> for CanDataFrame"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/default/trait.Default.js b/implementors/core/default/trait.Default.js new file mode 100644 index 0000000..1b4b491 --- /dev/null +++ b/implementors/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Default for NameBuilder"],["impl Default for Frame"],["impl Default for CanId"],["impl Default for NetworkManager"],["impl Default for Channel"],["impl Default for AddressClaimingState"],["impl Default for NAME"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/error/trait.Error.js b/implementors/core/error/trait.Error.js new file mode 100644 index 0000000..ddc5fef --- /dev/null +++ b/implementors/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Error for DriverReadError"],["impl Error for DriverWriteError"],["impl Error for DriverOpenError"],["impl Error for DriverCloseError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Debug.js b/implementors/core/fmt/trait.Debug.js new file mode 100644 index 0000000..2009838 --- /dev/null +++ b/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Debug for Frame"],["impl Debug for CANTransmitState"],["impl Debug for DriverCloseError"],["impl Debug for Priority"],["impl Debug for Type"],["impl Debug for Channel"],["impl Debug for CanId"],["impl Debug for DriverOpenError"],["impl Debug for Pgn"],["impl Debug for DriverReadError"],["impl Debug for Address"],["impl Debug for CommonParameterGroupNumbers"],["impl Debug for DriverWriteError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/fmt/trait.Display.js b/implementors/core/fmt/trait.Display.js new file mode 100644 index 0000000..4c318d4 --- /dev/null +++ b/implementors/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Display for DriverWriteError"],["impl Display for DriverOpenError"],["impl Display for DriverReadError"],["impl Display for DriverCloseError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/hash/trait.Hash.js b/implementors/core/hash/trait.Hash.js new file mode 100644 index 0000000..b42bb64 --- /dev/null +++ b/implementors/core/hash/trait.Hash.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Hash for Pgn"],["impl Hash for CanId"],["impl Hash for Address"],["impl Hash for Priority"],["impl Hash for Type"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Copy.js b/implementors/core/marker/trait.Copy.js new file mode 100644 index 0000000..73def38 --- /dev/null +++ b/implementors/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Copy for Address"],["impl Copy for CanId"],["impl Copy for NAME"],["impl Copy for NameField"],["impl Copy for AddressClaimingState"],["impl Copy for Priority"],["impl Copy for CANTransmitState"],["impl Copy for CommonParameterGroupNumbers"],["impl Copy for Pgn"],["impl Copy for Type"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Freeze.js b/implementors/core/marker/trait.Freeze.js new file mode 100644 index 0000000..7cb1a51 --- /dev/null +++ b/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Freeze for Address",1,["ag_iso_stack::driver::address::Address"]],["impl Freeze for Priority",1,["ag_iso_stack::driver::can_id::Priority"]],["impl Freeze for Type",1,["ag_iso_stack::driver::can_id::Type"]],["impl Freeze for CanId",1,["ag_iso_stack::driver::can_id::CanId"]],["impl Freeze for DriverOpenError",1,["ag_iso_stack::driver::driver::DriverOpenError"]],["impl Freeze for DriverCloseError",1,["ag_iso_stack::driver::driver::DriverCloseError"]],["impl Freeze for DriverReadError",1,["ag_iso_stack::driver::driver::DriverReadError"]],["impl Freeze for DriverWriteError",1,["ag_iso_stack::driver::driver::DriverWriteError"]],["impl Freeze for Channel",1,["ag_iso_stack::driver::frame::Channel"]],["impl Freeze for Frame",1,["ag_iso_stack::driver::frame::Frame"]],["impl Freeze for Pgn",1,["ag_iso_stack::driver::pgn::Pgn"]],["impl Freeze for SocketcanDriver",1,["ag_iso_stack::driver::socketcan::SocketcanDriver"]],["impl Freeze for CANMessage",1,["ag_iso_stack::network_management::can_message::CANMessage"]],["impl Freeze for CommonParameterGroupNumbers",1,["ag_iso_stack::network_management::common_parameter_group_numbers::CommonParameterGroupNumbers"]],["impl Freeze for AddressClaimingState",1,["ag_iso_stack::network_management::control_function::AddressClaimingState"]],["impl Freeze for AddressClaimingData",1,["ag_iso_stack::network_management::control_function::AddressClaimingData"]],["impl Freeze for ControlFunction",1,["ag_iso_stack::network_management::control_function::ControlFunction"]],["impl Freeze for NameField",1,["ag_iso_stack::network_management::name::NameField"]],["impl Freeze for NAME",1,["ag_iso_stack::network_management::name::NAME"]],["impl Freeze for NameBuilder",1,["ag_iso_stack::network_management::name::NameBuilder"]],["impl Freeze for CANTransmitState",1,["ag_iso_stack::network_management::network_manager::CANTransmitState"]],["impl Freeze for NetworkManager",1,["ag_iso_stack::network_management::network_manager::NetworkManager"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Send.js b/implementors/core/marker/trait.Send.js new file mode 100644 index 0000000..ffd8893 --- /dev/null +++ b/implementors/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Send for Address",1,["ag_iso_stack::driver::address::Address"]],["impl Send for Priority",1,["ag_iso_stack::driver::can_id::Priority"]],["impl Send for Type",1,["ag_iso_stack::driver::can_id::Type"]],["impl Send for CanId",1,["ag_iso_stack::driver::can_id::CanId"]],["impl Send for DriverOpenError",1,["ag_iso_stack::driver::driver::DriverOpenError"]],["impl Send for DriverCloseError",1,["ag_iso_stack::driver::driver::DriverCloseError"]],["impl Send for DriverReadError",1,["ag_iso_stack::driver::driver::DriverReadError"]],["impl Send for DriverWriteError",1,["ag_iso_stack::driver::driver::DriverWriteError"]],["impl Send for Channel",1,["ag_iso_stack::driver::frame::Channel"]],["impl Send for Frame",1,["ag_iso_stack::driver::frame::Frame"]],["impl Send for Pgn",1,["ag_iso_stack::driver::pgn::Pgn"]],["impl Send for SocketcanDriver",1,["ag_iso_stack::driver::socketcan::SocketcanDriver"]],["impl Send for CANMessage",1,["ag_iso_stack::network_management::can_message::CANMessage"]],["impl Send for CommonParameterGroupNumbers",1,["ag_iso_stack::network_management::common_parameter_group_numbers::CommonParameterGroupNumbers"]],["impl Send for AddressClaimingState",1,["ag_iso_stack::network_management::control_function::AddressClaimingState"]],["impl Send for AddressClaimingData",1,["ag_iso_stack::network_management::control_function::AddressClaimingData"]],["impl Send for ControlFunction",1,["ag_iso_stack::network_management::control_function::ControlFunction"]],["impl Send for NameField",1,["ag_iso_stack::network_management::name::NameField"]],["impl Send for NAME",1,["ag_iso_stack::network_management::name::NAME"]],["impl Send for NameBuilder",1,["ag_iso_stack::network_management::name::NameBuilder"]],["impl Send for CANTransmitState",1,["ag_iso_stack::network_management::network_manager::CANTransmitState"]],["impl !Send for NetworkManager",1,["ag_iso_stack::network_management::network_manager::NetworkManager"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.StructuralEq.js b/implementors/core/marker/trait.StructuralEq.js new file mode 100644 index 0000000..2d395b4 --- /dev/null +++ b/implementors/core/marker/trait.StructuralEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl StructuralEq for Type"],["impl StructuralEq for NameField"],["impl StructuralEq for Pgn"],["impl StructuralEq for AddressClaimingState"],["impl StructuralEq for CommonParameterGroupNumbers"],["impl StructuralEq for Priority"],["impl StructuralEq for CanId"],["impl StructuralEq for Address"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.StructuralPartialEq.js b/implementors/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 0000000..3832f13 --- /dev/null +++ b/implementors/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl StructuralPartialEq for NAME"],["impl StructuralPartialEq for Pgn"],["impl StructuralPartialEq for Priority"],["impl StructuralPartialEq for CanId"],["impl StructuralPartialEq for CommonParameterGroupNumbers"],["impl StructuralPartialEq for Address"],["impl StructuralPartialEq for NameField"],["impl StructuralPartialEq for AddressClaimingState"],["impl StructuralPartialEq for Type"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Sync.js b/implementors/core/marker/trait.Sync.js new file mode 100644 index 0000000..4d01a8c --- /dev/null +++ b/implementors/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Sync for Address",1,["ag_iso_stack::driver::address::Address"]],["impl Sync for Priority",1,["ag_iso_stack::driver::can_id::Priority"]],["impl Sync for Type",1,["ag_iso_stack::driver::can_id::Type"]],["impl Sync for CanId",1,["ag_iso_stack::driver::can_id::CanId"]],["impl Sync for DriverOpenError",1,["ag_iso_stack::driver::driver::DriverOpenError"]],["impl Sync for DriverCloseError",1,["ag_iso_stack::driver::driver::DriverCloseError"]],["impl Sync for DriverReadError",1,["ag_iso_stack::driver::driver::DriverReadError"]],["impl Sync for DriverWriteError",1,["ag_iso_stack::driver::driver::DriverWriteError"]],["impl Sync for Channel",1,["ag_iso_stack::driver::frame::Channel"]],["impl Sync for Frame",1,["ag_iso_stack::driver::frame::Frame"]],["impl Sync for Pgn",1,["ag_iso_stack::driver::pgn::Pgn"]],["impl Sync for SocketcanDriver",1,["ag_iso_stack::driver::socketcan::SocketcanDriver"]],["impl Sync for CANMessage",1,["ag_iso_stack::network_management::can_message::CANMessage"]],["impl Sync for CommonParameterGroupNumbers",1,["ag_iso_stack::network_management::common_parameter_group_numbers::CommonParameterGroupNumbers"]],["impl Sync for AddressClaimingState",1,["ag_iso_stack::network_management::control_function::AddressClaimingState"]],["impl Sync for AddressClaimingData",1,["ag_iso_stack::network_management::control_function::AddressClaimingData"]],["impl Sync for ControlFunction",1,["ag_iso_stack::network_management::control_function::ControlFunction"]],["impl Sync for NameField",1,["ag_iso_stack::network_management::name::NameField"]],["impl Sync for NAME",1,["ag_iso_stack::network_management::name::NAME"]],["impl Sync for NameBuilder",1,["ag_iso_stack::network_management::name::NameBuilder"]],["impl Sync for CANTransmitState",1,["ag_iso_stack::network_management::network_manager::CANTransmitState"]],["impl !Sync for NetworkManager",1,["ag_iso_stack::network_management::network_manager::NetworkManager"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/marker/trait.Unpin.js b/implementors/core/marker/trait.Unpin.js new file mode 100644 index 0000000..cd0fe68 --- /dev/null +++ b/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl Unpin for Address",1,["ag_iso_stack::driver::address::Address"]],["impl Unpin for Priority",1,["ag_iso_stack::driver::can_id::Priority"]],["impl Unpin for Type",1,["ag_iso_stack::driver::can_id::Type"]],["impl Unpin for CanId",1,["ag_iso_stack::driver::can_id::CanId"]],["impl Unpin for DriverOpenError",1,["ag_iso_stack::driver::driver::DriverOpenError"]],["impl Unpin for DriverCloseError",1,["ag_iso_stack::driver::driver::DriverCloseError"]],["impl Unpin for DriverReadError",1,["ag_iso_stack::driver::driver::DriverReadError"]],["impl Unpin for DriverWriteError",1,["ag_iso_stack::driver::driver::DriverWriteError"]],["impl Unpin for Channel",1,["ag_iso_stack::driver::frame::Channel"]],["impl Unpin for Frame",1,["ag_iso_stack::driver::frame::Frame"]],["impl Unpin for Pgn",1,["ag_iso_stack::driver::pgn::Pgn"]],["impl Unpin for SocketcanDriver",1,["ag_iso_stack::driver::socketcan::SocketcanDriver"]],["impl Unpin for CANMessage",1,["ag_iso_stack::network_management::can_message::CANMessage"]],["impl Unpin for CommonParameterGroupNumbers",1,["ag_iso_stack::network_management::common_parameter_group_numbers::CommonParameterGroupNumbers"]],["impl Unpin for AddressClaimingState",1,["ag_iso_stack::network_management::control_function::AddressClaimingState"]],["impl Unpin for AddressClaimingData",1,["ag_iso_stack::network_management::control_function::AddressClaimingData"]],["impl Unpin for ControlFunction",1,["ag_iso_stack::network_management::control_function::ControlFunction"]],["impl Unpin for NameField",1,["ag_iso_stack::network_management::name::NameField"]],["impl Unpin for NAME",1,["ag_iso_stack::network_management::name::NAME"]],["impl Unpin for NameBuilder",1,["ag_iso_stack::network_management::name::NameBuilder"]],["impl Unpin for CANTransmitState",1,["ag_iso_stack::network_management::network_manager::CANTransmitState"]],["impl Unpin for NetworkManager",1,["ag_iso_stack::network_management::network_manager::NetworkManager"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 0000000..5943af6 --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl RefUnwindSafe for Address",1,["ag_iso_stack::driver::address::Address"]],["impl RefUnwindSafe for Priority",1,["ag_iso_stack::driver::can_id::Priority"]],["impl RefUnwindSafe for Type",1,["ag_iso_stack::driver::can_id::Type"]],["impl RefUnwindSafe for CanId",1,["ag_iso_stack::driver::can_id::CanId"]],["impl !RefUnwindSafe for DriverOpenError",1,["ag_iso_stack::driver::driver::DriverOpenError"]],["impl RefUnwindSafe for DriverCloseError",1,["ag_iso_stack::driver::driver::DriverCloseError"]],["impl !RefUnwindSafe for DriverReadError",1,["ag_iso_stack::driver::driver::DriverReadError"]],["impl !RefUnwindSafe for DriverWriteError",1,["ag_iso_stack::driver::driver::DriverWriteError"]],["impl RefUnwindSafe for Channel",1,["ag_iso_stack::driver::frame::Channel"]],["impl RefUnwindSafe for Frame",1,["ag_iso_stack::driver::frame::Frame"]],["impl RefUnwindSafe for Pgn",1,["ag_iso_stack::driver::pgn::Pgn"]],["impl RefUnwindSafe for SocketcanDriver",1,["ag_iso_stack::driver::socketcan::SocketcanDriver"]],["impl RefUnwindSafe for CANMessage",1,["ag_iso_stack::network_management::can_message::CANMessage"]],["impl RefUnwindSafe for CommonParameterGroupNumbers",1,["ag_iso_stack::network_management::common_parameter_group_numbers::CommonParameterGroupNumbers"]],["impl RefUnwindSafe for AddressClaimingState",1,["ag_iso_stack::network_management::control_function::AddressClaimingState"]],["impl RefUnwindSafe for AddressClaimingData",1,["ag_iso_stack::network_management::control_function::AddressClaimingData"]],["impl RefUnwindSafe for ControlFunction",1,["ag_iso_stack::network_management::control_function::ControlFunction"]],["impl RefUnwindSafe for NameField",1,["ag_iso_stack::network_management::name::NameField"]],["impl RefUnwindSafe for NAME",1,["ag_iso_stack::network_management::name::NAME"]],["impl RefUnwindSafe for NameBuilder",1,["ag_iso_stack::network_management::name::NameBuilder"]],["impl RefUnwindSafe for CANTransmitState",1,["ag_iso_stack::network_management::network_manager::CANTransmitState"]],["impl !RefUnwindSafe for NetworkManager",1,["ag_iso_stack::network_management::network_manager::NetworkManager"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 0000000..09df06f --- /dev/null +++ b/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"ag_iso_stack":[["impl UnwindSafe for Address",1,["ag_iso_stack::driver::address::Address"]],["impl UnwindSafe for Priority",1,["ag_iso_stack::driver::can_id::Priority"]],["impl UnwindSafe for Type",1,["ag_iso_stack::driver::can_id::Type"]],["impl UnwindSafe for CanId",1,["ag_iso_stack::driver::can_id::CanId"]],["impl !UnwindSafe for DriverOpenError",1,["ag_iso_stack::driver::driver::DriverOpenError"]],["impl UnwindSafe for DriverCloseError",1,["ag_iso_stack::driver::driver::DriverCloseError"]],["impl !UnwindSafe for DriverReadError",1,["ag_iso_stack::driver::driver::DriverReadError"]],["impl !UnwindSafe for DriverWriteError",1,["ag_iso_stack::driver::driver::DriverWriteError"]],["impl UnwindSafe for Channel",1,["ag_iso_stack::driver::frame::Channel"]],["impl UnwindSafe for Frame",1,["ag_iso_stack::driver::frame::Frame"]],["impl UnwindSafe for Pgn",1,["ag_iso_stack::driver::pgn::Pgn"]],["impl UnwindSafe for SocketcanDriver",1,["ag_iso_stack::driver::socketcan::SocketcanDriver"]],["impl UnwindSafe for CANMessage",1,["ag_iso_stack::network_management::can_message::CANMessage"]],["impl UnwindSafe for CommonParameterGroupNumbers",1,["ag_iso_stack::network_management::common_parameter_group_numbers::CommonParameterGroupNumbers"]],["impl UnwindSafe for AddressClaimingState",1,["ag_iso_stack::network_management::control_function::AddressClaimingState"]],["impl UnwindSafe for AddressClaimingData",1,["ag_iso_stack::network_management::control_function::AddressClaimingData"]],["impl UnwindSafe for ControlFunction",1,["ag_iso_stack::network_management::control_function::ControlFunction"]],["impl UnwindSafe for NameField",1,["ag_iso_stack::network_management::name::NameField"]],["impl UnwindSafe for NAME",1,["ag_iso_stack::network_management::name::NAME"]],["impl UnwindSafe for NameBuilder",1,["ag_iso_stack::network_management::name::NameBuilder"]],["impl UnwindSafe for CANTransmitState",1,["ag_iso_stack::network_management::network_manager::CANTransmitState"]],["impl !UnwindSafe for NetworkManager",1,["ag_iso_stack::network_management::network_manager::NetworkManager"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..507d80f --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + diff --git a/search-index.js b/search-index.js new file mode 100644 index 0000000..67b00f6 --- /dev/null +++ b/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = JSON.parse('{\ +"ag_iso_stack":{"doc":"","t":"AADSNDDSIENNEEENNNNDSSNNNSSSNNNDENNDNNNENLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLKLMMLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMLLLLLLLLLLLLLLLKLLLLKLLLLLLLLLLLKLLLMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKLAAAAADLLLLLLLLLLLLNNNNNNNNENNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNLLLLLLLLLLLLLLNDENENNNNNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMNNNNNNNNNDDENNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLENDNLLLLLLLLLLLLLLLLLLLLLLLLLL","n":["driver","network_management","Address","BROADCAST","BusError","CanId","Channel","Default","Driver","DriverCloseError","DriverClosed","DriverClosed","DriverOpenError","DriverReadError","DriverWriteError","ErrorFrame","Extended","Five","Four","Frame","GLOBAL","Highest","IoError","IoError","IoError","Lowest","NULL","NULL","NoFrameReady","NotReady","One","Pgn","Priority","Seven","Six","SocketcanDriver","Standard","Three","Two","Type","Zero","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","channel","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","close","close","data","data_length","data_page","default","default","default","destination_address","encode_unchecked","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","extended","extended_data_page","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_id","from_raw","hash","hash","hash","hash","hash","id","into","into","into","into","into","into","into","into","into","into","into","into","is_broadcast","is_destination_specific","is_proprietary","is_valid","is_valid","new","new_by_index","new_by_name","open","open","pdu_format","pdu_specific","pgn","priority","provide","provide","provide","provide","raw","raw","read_nonblocking","read_nonblocking","source","source_address","timestamp","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","try_encode","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","type_","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","write_nonblocking","write_nonblocking","can_message","common_parameter_group_numbers","control_function","name","network_manager","CANMessage","borrow","borrow_mut","from","get_data","get_destination_name","get_identifier","get_source_name","into","try_from","try_into","type_id","vzip","Acknowledgement","ActiveDiagnosticTroubleCodes","AddressClaim","AllowAll","AuthenticationClientToAuthenticationServer","AuthenticationServerToAuthenticationClient","BinaryDataTransfer","CommandedAddress","CommonParameterGroupNumbers","ControlFunctionFunctionalities","CruiseControlVehicleSpeed1","DiagnosticDataClearResetForActiveDtcs","DiagnosticDataClearResetOfPreviouslyActiveDtcs","DiagnosticProtocol","EcuIdentificationInformation","ElectronicEngineController1","ElectronicEngineController2","EngineTemperature1","ExtendedTransportProtocolCommand","ExtendedTransportProtocolData","FreezeFrameParameters","GroundBasedSpeedAndDistance","GuidanceMachineStatus","GuidanceSystemCommand","HeartbeatMessage","IntakeExhaustConditions1","IsobusComplianceCertificationMessage","MaintainPower","MemoryAccessRequest","MemoryAccessResponse","NameManagement","NmeaAltitudeDeltaHighPrecisionRapidUpdate","NmeaAttitude","NmeaCogSogRapidUpdate","NmeaGnssDops","NmeaGnssPositionData","NmeaGnssPseudoRangeErrorStatistics","NmeaGnssPseudoRangeNoiseStatistics","NmeaGnssSatsInView","NmeaPositionDeltaHighPrecisionRapidUpdate","NmeaTimeDate","NodeToVirtualTerminal","ParameterGroupNumberRequest","PreviouslyActiveDiagnosticTroubleCodes","ProductIdentification","ProprietaryA","RequestForRepetitionRate","ResponseForRepetitionRate","SoftwareIdentification","StopStartBroadcast","TimeDate","TractorImplementManagementClientToTimServer","TractorImplementManagementServerToTimClient","TransportProtocolCommand","TransportProtocolData","VirtualTerminalToNode","WheelBasedSpeedAndDistance","WorkingSetMaster","borrow","borrow_mut","clone","clone_into","eq","equivalent","fmt","from","into","to_owned","try_from","try_into","type_id","vzip","AddressClaimingComplete","AddressClaimingData","AddressClaimingState","ContendForPreferredAddress","ControlFunction","External","Internal","None","SendArbitraryAddressClaim","SendPreferredAddressClaim","SendReclaimAddressOnRequest","SendRequestForClaim","UnableToClaim","WaitForClaim","WaitForRequestContentionPeriod","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","default","eq","equivalent","from","from","from","get_enabled","get_name","get_name","get_preferred_address","get_state","get_timestamp","into","into","into","new","new_internal_control_function","set_enabled","set_name","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","address_claim_data","name","DeviceClass","DeviceClassInstance","EcuInstance","ExtendedIdentityNumber","Function","FunctionInstance","IdentityNumber","IndustryGroup","ManufacturerCode","NAME","NameBuilder","NameField","SelfConfigurableAddress","ShortIdentityNumber","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","build","builder","clone","clone","clone_into","clone_into","default","default","device_class","device_class_instance","ecu_instance","eq","eq","equivalent","from","from","from","from","function_code","function_instance","get_device_class","get_device_class_instance","get_ecu_instance","get_extended_identity_number","get_function","get_function_instance","get_identity_number","get_industry_group","get_manufacturer_code","get_self_configurable_address","get_short_identity_number","has_field_value","has_field_values","identity_number","industry_group","into","into","into","manufacturer_code","new","new","self_configurable_address","set_device_class","set_device_class_instance","set_ecu_instance","set_extended_identity_number","set_function","set_function_instance","set_identity_number","set_industry_group","set_manufacturer_code","set_self_configurable_address","set_short_identity_number","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","CANTransmitState","Fail","NetworkManager","Success","borrow","borrow","borrow_mut","borrow_mut","clone","clone_into","default","fmt","from","from","get_control_function_address_by_name","get_control_function_by_address","into","into","new","send_can_message","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","update","vzip","vzip"],"q":[[0,"ag_iso_stack"],[2,"ag_iso_stack::driver"],[237,"ag_iso_stack::network_management"],[242,"ag_iso_stack::network_management::can_message"],[255,"ag_iso_stack::network_management::common_parameter_group_numbers"],[327,"ag_iso_stack::network_management::control_function"],[382,"ag_iso_stack::network_management::control_function::ControlFunction"],[384,"ag_iso_stack::network_management::name"],[471,"ag_iso_stack::network_management::network_manager"]],"d":["CAN Driver layer","","","Alias for the global address","Some fault with the CAN bus","","","","Generic interface for CAN drivers","","The driver has been closed","The driver has been closed","","","","The driver received an error frame","29-bit CAN ID","","","","Address representing broadcasts for destination specific …","","The driver failed to open with filesystem semantics","The driver failed to read with filesystem semantics","Some fault with filesystem semantics","","The null address is used by ECUs without an address such …","A fake PGN used to denote a PGN that does not exist","There is no frame ready to be read","The driver’s internal buffer is full, or the driver is …","","","","You may also use Priority::Lowest as an alias","You may also use Priority::Default as an alias","A Linux socketcan Driver","11-bit CAN ID","","","","You may also use Priority::Highest as an alias","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Close the driver","","","","","","","","Get the destination address for this CAN ID, if it’s a …","Encodes a new extended ID using the discrete parts of an …","","","","","","","","","","","","","","","","","","","","","","","","","","","","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.","","","","","","","","","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).","","","","Determine whether the driver is connected and healthy","","","Create a socketcan driver with the given interface index","Create a socketcan driver with the given interface name. …","Open the driver","","","","Get the ID’s PGN","Get the priority of the ID","","","","","Get the raw value of the CAN ID","","Read a Frame from the driver, if possible","Read a frame from the driver, if possible","","Get the source address of the ID","","","","","","","","","","","Encodes a new extended ID using the discrete parts of an …","","","","","","","","","","","","","","","","","","","","","","","","","Get the type of the ID (standard or extended)","","","","","","","","","","","","","","","","","","","","","","","","","Write a Frame to the driver, if possible","","","","","","","","","","Returns the argument unchanged.","","","","","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self).","","","","","","Address claiming is complete and we have an address ","","","State machine is contending the preferred address ","","","","Address claiming is uninitialized","State machine is claiming an address ","State machine is claiming the preferred address","An ECU requested address claim, inform the bus of our …","State machine is sending the request for address claim …","State machine could not claim an address","State machine is waiting for the random delay time …","State machine is waiting for the address claim contention …","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Returns the argument unchanged.","","","","","","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Used to describe that a CAN message was not accepted by …","","Used to describe that a CAN message was accepted by the …","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","",""],"i":[0,0,0,1,17,0,0,2,0,0,16,17,0,0,0,16,3,2,2,0,1,2,15,16,17,2,1,5,16,17,2,0,0,2,2,0,3,2,2,0,2,8,1,2,3,4,15,6,16,17,10,11,5,8,1,2,3,4,15,6,16,17,10,11,5,11,1,2,3,4,5,1,2,3,4,5,45,8,11,11,5,4,10,11,4,4,1,2,3,4,5,1,2,3,4,5,11,5,1,2,3,4,15,15,6,6,16,16,17,17,10,11,5,8,1,2,2,3,4,15,15,6,16,16,16,17,17,17,10,11,5,5,5,1,2,3,4,5,11,8,1,2,3,4,15,6,16,17,10,11,5,5,5,5,45,8,4,8,8,45,8,5,5,4,4,15,6,16,17,4,5,45,8,15,4,11,1,2,3,4,5,15,6,16,17,4,8,1,2,3,4,15,6,16,17,10,11,5,8,1,2,3,4,15,6,16,17,10,11,5,4,8,1,2,3,4,15,6,16,17,10,11,5,8,1,2,3,4,15,6,16,17,10,11,5,45,8,0,0,0,0,0,0,28,28,28,28,28,28,28,28,28,28,28,28,31,31,31,31,31,31,31,31,0,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,32,0,0,32,0,34,34,32,32,32,32,32,32,32,32,33,34,32,33,34,32,32,32,32,32,32,33,34,32,33,33,34,33,33,33,33,34,32,33,34,33,33,32,33,34,32,33,34,32,33,34,32,33,34,32,46,47,40,40,40,40,40,40,40,40,40,0,0,0,40,40,40,30,39,40,30,39,39,30,40,30,40,30,30,39,39,39,39,40,30,40,40,30,39,39,39,39,30,30,30,30,30,30,30,30,30,30,30,30,30,39,39,40,30,39,39,30,39,39,30,30,30,30,30,30,30,30,30,30,30,40,30,40,30,39,40,30,39,40,30,39,40,30,39,0,44,0,44,36,44,36,44,44,44,36,44,36,44,36,36,36,44,36,36,44,36,44,36,44,36,44,36,36,44],"f":[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,[1,1],[2,2],[3,3],[4,4],[5,5],[[]],[[]],[[]],[[]],[[]],[[],[[7,[6]]]],[8,[[7,[6]]]],0,0,[5,9],[[],4],[[],10],[[],11],[4,1],[[5,1,1,2],4],[[1,1],12],[[2,2],12],[[3,3],12],[[4,4],12],[[5,5],12],[[],12],[[],12],[[],12],[[],12],[[],12],0,[5,9],[[1,13],14],[[2,13],14],[[3,13],14],[[4,13],14],[[15,13],14],[[15,13],14],[[6,13],14],[[6,13],14],[[16,13],14],[[16,13],14],[[17,13],14],[[17,13],14],[[10,13],14],[[11,13],14],[[5,13],14],[[]],[[]],[[]],[9,2],[[]],[[]],[[]],[18,15],[[]],[[]],[18,16],[19,16],[18,17],[[]],[19,17],[[]],[[]],[[]],[20,5],[20,5],[[1,21]],[[2,21]],[[3,21]],[[4,21]],[[5,21]],0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[5,12],[5,12],[5,12],[[],12],[8,12],[[20,3],4],[20,8],[22,8],[[],[[7,[15]]]],[8,[[7,[15]]]],[5,9],[5,9],[4,5],[4,2],[23],[23],[23],[23],[4,20],[5,20],[11,[[7,[16]]]],[[8,11],[[7,[16]]]],[15,[[25,[24]]]],[4,1],0,[[]],[[]],[[]],[[]],[[]],[[],26],[[],26],[[],26],[[],26],[[5,1,1,2],[[7,[4,0]]]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[4,3],[[],27],[[],27],[[],27],[[],27],[[],27],[[],27],[[],27],[[],27],[[],27],[[],27],[[],27],[[],27],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[11,[[7,[17]]]],[[8,11],[[7,[17]]]],0,0,0,0,0,0,[[]],[[]],[[]],[28,[[29,[9]]]],[28,30],[28,4],[28,30],[[]],[[],7],[[],7],[[],27],[[]],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,0,[[]],[[]],[31,31],[[]],[[31,31],12],[[],12],[[31,13],14],[[]],[[]],[[]],[[],7],[[],7],[[],27],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[32,32],[[]],[[],32],[[32,32],12],[[],12],[[]],[[]],[[]],[33,12],[33,30],[34,30],[33,1],[33,32],[33,[[25,[35]]]],[[]],[[]],[[]],[[30,1,12],33],[[30,1,12,36],[[38,[[37,[34]]]]]],[[33,12]],[[33,30]],[[]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],27],[[],27],[[],27],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[39,30],[[],39],[40,40],[30,30],[[]],[[]],[[],30],[[],39],[[39,[41,[9]]],39],[[39,[41,[9]]],39],[[39,[41,[9]]],39],[[40,40],12],[[30,30],12],[[],12],[[]],[[]],[30,39],[[]],[[39,[41,[9]]],39],[[39,[41,[9]]],39],[30,9],[30,9],[30,9],[30,9],[30,9],[30,9],[30,20],[30,9],[30,42],[30,12],[30,42],[[30,40],12],[[30,[29,[40]]],12],[[39,[41,[20]]],39],[[39,[41,[9]]],39],[[]],[[]],[[]],[[39,[41,[42]]],39],[43,30],[[],39],[[39,[41,[12]]],39],[[30,9]],[[30,9]],[[30,9]],[[30,9]],[[30,9]],[[30,9]],[[30,20]],[[30,9]],[[30,42]],[[30,12]],[[30,42]],[[]],[[]],[[],7],[[],7],[[],7],[[],7],[[],7],[[],7],[[],27],[[],27],[[],27],[[]],[[]],[[]],0,0,0,0,[[]],[[]],[[]],[[]],[44,44],[[]],[[],36],[[44,13],14],[[]],[[]],[[36,30],1],[[36,1],[[25,[[38,[[37,[34]]]]]]]],[[]],[[]],[[],36],[[36,5,[29,[9]],[38,[[37,[34]]]],[38,[[37,[34]]]],2],44],[[]],[[],7],[[],7],[[],7],[[],7],[[],27],[[],27],[36],[[]],[[]]],"c":[],"p":[[3,"Address"],[4,"Priority"],[4,"Type"],[3,"CanId"],[3,"Pgn"],[4,"DriverCloseError"],[4,"Result"],[3,"SocketcanDriver"],[15,"u8"],[3,"Channel"],[3,"Frame"],[15,"bool"],[3,"Formatter"],[6,"Result"],[4,"DriverOpenError"],[4,"DriverReadError"],[4,"DriverWriteError"],[3,"Error"],[4,"Error"],[15,"u32"],[8,"Hasher"],[15,"str"],[3,"Demand"],[8,"Error"],[4,"Option"],[3,"String"],[3,"TypeId"],[3,"CANMessage"],[15,"slice"],[3,"NAME"],[4,"CommonParameterGroupNumbers"],[4,"AddressClaimingState"],[3,"AddressClaimingData"],[4,"ControlFunction"],[3,"Instant"],[3,"NetworkManager"],[3,"RefCell"],[3,"Rc"],[3,"NameBuilder"],[4,"NameField"],[8,"Into"],[15,"u16"],[15,"u64"],[4,"CANTransmitState"],[8,"Driver"],[13,"Internal"],[13,"External"]]}\ +}'); +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..0cc175b --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Rustdoc settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/source-files.js b/source-files.js new file mode 100644 index 0000000..c08cd36 --- /dev/null +++ b/source-files.js @@ -0,0 +1,4 @@ +var sourcesIndex = JSON.parse('{\ +"ag_iso_stack":["",[["driver",[],["address.rs","can_id.rs","driver.rs","frame.rs","mod.rs","pgn.rs","socketcan.rs"]],["network_management",[],["can_message.rs","common_parameter_group_numbers.rs","control_function.rs","mod.rs","name.rs","network_manager.rs"]]],["lib.rs"]]\ +}'); +createSourceSidebar(); diff --git a/src/ag_iso_stack/driver/address.rs.html b/src/ag_iso_stack/driver/address.rs.html new file mode 100644 index 0000000..5e8bbb5 --- /dev/null +++ b/src/ag_iso_stack/driver/address.rs.html @@ -0,0 +1,33 @@ +address.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+
// Copyright 2023 Raven Industries inc.
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[repr(transparent)]
+pub struct Address(pub u8);
+
+impl Address {
+    /// Address representing broadcasts for destination specific PGNs
+    pub const GLOBAL: Address = Address(0xFF);
+    /// Alias for the global address
+    pub const BROADCAST: Address = Address(0xFF);
+    /// The null address is used by ECUs without an address such as during address claiming
+    pub const NULL: Address = Address(0xFE);
+}
+
+// TODO: custom Debug impl and helpers
+
\ No newline at end of file diff --git a/src/ag_iso_stack/driver/can_id.rs.html b/src/ag_iso_stack/driver/can_id.rs.html new file mode 100644 index 0000000..0205f44 --- /dev/null +++ b/src/ag_iso_stack/driver/can_id.rs.html @@ -0,0 +1,595 @@ +can_id.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
+
// Copyright 2023 Raven Industries inc.
+use crate::driver::{Address, Pgn};
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum Priority {
+    /// You may also use [`Priority::Highest`] as an alias
+    Zero = 0x0,
+    One = 0x1,
+    Two = 0x2,
+    Three = 0x3,
+    Four = 0x4,
+    Five = 0x5,
+    /// You may also use [`Priority::Default`] as an alias
+    Six = 0x6,
+    /// You may also use [`Priority::Lowest`] as an alias
+    Seven = 0x7,
+}
+
+#[allow(non_upper_case_globals)]
+impl Priority {
+    pub const Highest: Priority = Priority::Zero;
+    pub const Default: Priority = Priority::Six;
+    pub const Lowest: Priority = Priority::Seven;
+}
+
+impl From<u8> for Priority {
+    fn from(value: u8) -> Priority {
+        match value {
+            0x0 => Priority::Zero,
+            0x1 => Priority::One,
+            0x2 => Priority::Two,
+            0x3 => Priority::Three,
+            0x4 => Priority::Four,
+            0x5 => Priority::Five,
+            0x6 => Priority::Six,
+            0x7 => Priority::Seven,
+            _ => unreachable!(
+                "Internal error converting a value larger than 3 bits to a CAN ID priority"
+            ),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum Type {
+    /// 11-bit CAN ID
+    Standard = 0x0,
+    /// 29-bit CAN ID
+    Extended = 0x1,
+}
+
+#[derive(Debug, Clone)]
+pub struct EncodingError {
+    pub priority: Priority,
+    pub parameter_group_number: Pgn,
+    pub source_address: Address,
+    pub destination_address: Address,
+}
+
+#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
+#[repr(transparent)]
+pub struct CanId(u32);
+
+// Linux uses the top three unused bits to indicate whether the frame is standard/extended, remote,
+// or an error frame. We do the same, because it's convenient.
+const CAN_EFF_FLAG: u32 = 0x80000000;
+// const CAN_RTR_FLAG: u32 = 0x40000000;
+// const CAN_ERR_FLAG: u32 = 0x20000000;
+
+const CAN_EFF_MASK: u32 = 0x1FFFFFFF;
+const CAN_SFF_MASK: u32 = 0x000007FF;
+
+impl CanId {
+    pub fn new(raw: u32, type_: Type) -> Self {
+        let raw = match type_ {
+            Type::Extended => (raw & CAN_EFF_MASK) | CAN_EFF_FLAG,
+            Type::Standard => raw & CAN_SFF_MASK,
+        };
+        Self(raw)
+    }
+
+    /// Encodes a new extended ID using the discrete parts of an identifier
+    pub fn try_encode(
+        parameter_group_number: Pgn,
+        source_address: Address,
+        destination_address: Address,
+        priority: Priority,
+    ) -> Result<CanId, EncodingError> {
+        if destination_address != Address::GLOBAL && parameter_group_number.is_broadcast() {
+            return Err(EncodingError {
+                priority,
+                parameter_group_number,
+                source_address,
+                destination_address,
+            });
+        }
+        Ok(unsafe {
+            CanId::encode_unchecked(
+                parameter_group_number,
+                source_address,
+                destination_address,
+                priority,
+            )
+        })
+    }
+
+    /// Encodes a new extended ID using the discrete parts of an identifier but won't validate
+    /// your combination of PGN and destination address.
+    ///
+    /// # Safety
+    /// Calling this without validating your PGN and destination address combination may result in your PGN field
+    /// getting trashed. Specifically, the risk is when you are using a broadcast PGN but supply a non-0xFF
+    /// destination address.
+    pub unsafe fn encode_unchecked(
+        parameter_group_number: Pgn,
+        source_address: Address,
+        destination_address: Address,
+        priority: Priority,
+    ) -> CanId {
+        let mut raw_id: u32 = 0;
+
+        raw_id |= (priority as u32 & 0x07) << 26;
+        raw_id |= source_address.0 as u32;
+
+        if Address::GLOBAL == destination_address {
+            if (parameter_group_number.raw() & 0xF000) >= 0xF000 {
+                raw_id |= (parameter_group_number.raw() & 0x3FFFF) << 8;
+            } else {
+                raw_id |= (destination_address.0 as u32) << 8;
+                raw_id |= (parameter_group_number.raw() & 0x3FF00) << 8;
+            }
+        } else if (parameter_group_number.raw() & 0xF000) < 0xF000 {
+            raw_id |= (destination_address.0 as u32) << 8;
+            raw_id |= (parameter_group_number.raw() & 0x3FF00) << 8;
+        }
+        CanId::new(raw_id & CAN_EFF_MASK, Type::Extended)
+    }
+
+    /// Get the raw value of the CAN ID
+    #[inline]
+    pub fn raw(&self) -> u32 {
+        match self.type_() {
+            Type::Extended => self.0 & CAN_EFF_MASK,
+            Type::Standard => self.0 & CAN_SFF_MASK,
+        }
+    }
+
+    /// Get the type of the ID (standard or extended)
+    #[inline]
+    pub fn type_(&self) -> Type {
+        if self.0 & CAN_EFF_FLAG != 0 {
+            Type::Extended
+        } else {
+            Type::Standard
+        }
+    }
+
+    /// Get the priority of the ID
+    #[inline]
+    pub fn priority(&self) -> Priority {
+        match self.type_() {
+            Type::Standard => Priority::Highest,
+            Type::Extended => {
+                let raw = ((self.raw() & 0x1C000000) >> 26) as u8;
+                raw.into()
+            }
+        }
+    }
+
+    /// Get the source address of the ID
+    #[inline]
+    pub fn source_address(&self) -> Address {
+        match self.type_() {
+            Type::Standard => Address::GLOBAL,
+            Type::Extended => Address((self.raw() & 0xFF) as u8),
+        }
+    }
+
+    /// Get the ID's PGN
+    ///
+    /// In the case the the ID is a standard 11-bit ID, a NULL PGN will be returned.
+    #[inline]
+    pub fn pgn(&self) -> Pgn {
+        match self.type_() {
+            Type::Standard => Pgn::NULL,
+            Type::Extended => Pgn::from_id(self.raw()),
+        }
+    }
+
+    /// Get the destination address for this CAN ID, if it's a destination-specific PGN
+    #[inline]
+    pub fn destination_address(&self) -> Address {
+        let pgn = self.pgn();
+        if pgn == Pgn::NULL || pgn.is_broadcast() {
+            return Address::GLOBAL;
+        }
+
+        let raw_pdu_s = ((self.raw() & 0xFF00) >> 8) as u8;
+        Address(raw_pdu_s)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_priority() {
+        let can_id = CanId::new(0x18EF1CF5, Type::Extended);
+        assert_eq!(can_id.priority(), Priority::Default);
+    }
+
+    #[test]
+    fn test_source_address() {
+        let can_id = CanId::new(0x0705, Type::Standard);
+        assert_eq!(can_id.type_(), Type::Standard);
+        // TODO: Is this right? Do 11-bit IDs always have a global address?
+        assert_eq!(can_id.source_address(), Address::GLOBAL);
+
+        let can_id = CanId::new(0x18EF1CF5, Type::Extended);
+        assert_eq!(can_id.source_address(), Address(0xF5));
+    }
+
+    #[test]
+    fn test_destination_address() {
+        let can_id = CanId::new(0x0705, Type::Standard);
+        assert_eq!(can_id.destination_address(), Address::GLOBAL);
+
+        let can_id = CanId::new(0x18EEFF1C, Type::Extended);
+        assert_eq!(can_id.destination_address(), Address::GLOBAL);
+
+        let can_id = CanId::new(0x09F8031C, Type::Extended);
+        assert_eq!(can_id.destination_address(), Address::GLOBAL);
+
+        let can_id = CanId::new(0x0CAC1C13, Type::Extended);
+        assert_eq!(can_id.destination_address(), Address(0x1C));
+    }
+
+    #[test]
+    fn test_pgn() {
+        let can_id = CanId::new(0x07FF, Type::Standard);
+        assert_eq!(can_id.pgn(), Pgn::NULL);
+
+        let can_id = CanId::new(0x0CAC1C13, Type::Extended);
+        assert_eq!(can_id.pgn(), Pgn::from_raw(0x0AC00));
+
+        let can_id = CanId::new(0x18FF3F13, Type::Extended);
+        assert_eq!(can_id.pgn(), Pgn::from_raw(0x0FF3F));
+
+        let can_id = CanId::new(0x18EF1CF5, Type::Extended);
+        assert_eq!(can_id.pgn(), Pgn::from_raw(0x0EF00));
+
+        let can_id = CanId::new(0x18EEFF1C, Type::Extended);
+        assert_eq!(can_id.pgn(), Pgn::from_raw(0x0EE00));
+    }
+
+    #[test]
+    fn test_encode() {
+        let encode_result = CanId::try_encode(
+            Pgn::from_raw(0x00EF00),
+            Address(0x81),
+            Address(0xF9),
+            Priority::Six,
+        );
+        let can_id = encode_result.expect("EF00 Message was not encodable");
+        assert_eq!(can_id.pgn(), Pgn::from_raw(0xEF00));
+        assert_eq!(can_id.destination_address(), Address(0xF9));
+        assert_eq!(can_id.source_address(), Address(0x81));
+        assert_eq!(can_id.priority(), Priority::Six);
+
+        let encode_result = CanId::try_encode(
+            Pgn::from_raw(0x00FF40),
+            Address(0x81),
+            Address(0xFF),
+            Priority::Six,
+        );
+        let can_id = encode_result.expect("FF40 Message was not encodable");
+        assert_eq!(can_id.pgn(), Pgn::from_raw(0xFF40));
+        assert_eq!(can_id.destination_address(), Address(0xFF));
+        assert_eq!(can_id.source_address(), Address(0x81));
+        assert_eq!(can_id.priority(), Priority::Six);
+
+        let encode_result = CanId::try_encode(
+            Pgn::from_raw(0x00FF40),
+            Address(0x81),
+            Address(0x0F),
+            Priority::Six,
+        );
+        assert!(encode_result.is_err());
+
+        let error_contents: EncodingError = encode_result.unwrap_err();
+        assert_eq!(error_contents.priority, Priority::Six);
+        assert_eq!(error_contents.source_address, Address(0x81));
+        assert_eq!(error_contents.destination_address, Address(0x0F));
+        assert_eq!(error_contents.parameter_group_number, Pgn::from_raw(0xFF40));
+    }
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/driver/driver.rs.html b/src/ag_iso_stack/driver/driver.rs.html new file mode 100644 index 0000000..1343e3d --- /dev/null +++ b/src/ag_iso_stack/driver/driver.rs.html @@ -0,0 +1,279 @@ +driver.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
+
// Copyright 2023 Raven Industries inc.
+use crate::driver::Frame;
+
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum DriverOpenError {
+    /// The driver failed to open with filesystem semantics
+    IoError(std::io::Error),
+}
+
+impl std::fmt::Display for DriverOpenError {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "Failed to open driver: {:?}", self)
+    }
+}
+impl std::error::Error for DriverOpenError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match &self {
+            DriverOpenError::IoError(e) => Some(e),
+        }
+    }
+}
+
+impl From<std::io::Error> for DriverOpenError {
+    fn from(e: std::io::Error) -> DriverOpenError {
+        DriverOpenError::IoError(e)
+    }
+}
+
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum DriverCloseError {}
+
+impl std::fmt::Display for DriverCloseError {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?}", self)
+    }
+}
+impl std::error::Error for DriverCloseError {}
+
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum DriverReadError {
+    /// There is no frame ready to be read
+    NoFrameReady,
+    /// The driver has been closed
+    DriverClosed,
+    /// The driver received an error frame
+    ErrorFrame(),
+    /// The driver failed to read with filesystem semantics
+    IoError(std::io::Error),
+}
+
+impl std::fmt::Display for DriverReadError {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?}", self)
+    }
+}
+impl std::error::Error for DriverReadError {}
+
+impl From<std::io::Error> for DriverReadError {
+    fn from(e: std::io::Error) -> DriverReadError {
+        if matches!(e.kind(), std::io::ErrorKind::WouldBlock) {
+            DriverReadError::NoFrameReady
+        } else {
+            DriverReadError::IoError(e)
+        }
+    }
+}
+
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum DriverWriteError {
+    /// The driver's internal buffer is full, or the driver is otherwise busy
+    NotReady,
+    /// The driver has been closed
+    DriverClosed,
+    /// Some fault with the CAN bus
+    BusError(),
+    /// Some fault with filesystem semantics
+    IoError(std::io::Error),
+}
+
+impl std::fmt::Display for DriverWriteError {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?}", self)
+    }
+}
+impl std::error::Error for DriverWriteError {}
+
+impl From<std::io::Error> for DriverWriteError {
+    fn from(e: std::io::Error) -> DriverWriteError {
+        if matches!(e.kind(), std::io::ErrorKind::WouldBlock) {
+            DriverWriteError::NotReady
+        } else {
+            DriverWriteError::IoError(e)
+        }
+    }
+}
+
+/// Generic interface for CAN drivers
+///
+/// This layer is meant to abstract the hardware, and should not do its own queuing/buffering.
+///
+/// This trait does _not_ define how to construct and configure a driver, as the details are likely
+/// to differ from driver to driver.
+pub trait Driver {
+    /// Determine whether the driver is connected and healthy
+    fn is_valid(&self) -> bool;
+
+    /// Open the driver
+    ///
+    /// It is expected you must open the driver after creating it
+    fn open(&mut self) -> Result<(), DriverOpenError>;
+
+    /// Close the driver
+    ///
+    /// It is not necessary to close the driver before dropping it
+    fn close(&mut self) -> Result<(), DriverCloseError>;
+
+    /// Read a [Frame] from the driver, if possible
+    ///
+    /// This is a non-blocking read. If there is no frame ready to read, this function will return
+    /// [DriverReadError::NoFrameReady].
+    ///
+    /// An out-parameter is used, so that the user can choose whether to construct a new frame for
+    /// each call, or to re-use memory.
+    fn read_nonblocking(&mut self, frame: &mut Frame) -> Result<(), DriverReadError>;
+
+    /// Write a [Frame] to the driver, if possible
+    ///
+    /// This is a non-blocking write. If the frame cannot be written because the driver's
+    /// queue/buffer is full (for drivers like `socketcan` that do internal buffering), or if
+    /// it's otherwise busy, this function will return [DriverWriteError::NotReady].
+    ///
+    /// For drivers that defer to some other implementation (Peak, Socketcan), it's likely that the
+    /// given `frame` is copied before being written.
+    fn write_nonblocking(&mut self, frame: &Frame) -> Result<(), DriverWriteError>;
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/driver/frame.rs.html b/src/ag_iso_stack/driver/frame.rs.html new file mode 100644 index 0000000..38f4423 --- /dev/null +++ b/src/ag_iso_stack/driver/frame.rs.html @@ -0,0 +1,39 @@ +frame.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+
// Copyright 2023 Raven Industries inc.
+use crate::driver::CanId;
+
+#[derive(Debug, Default)]
+#[repr(transparent)]
+pub struct Channel(u8);
+
+#[derive(Debug, Default)]
+pub struct Frame {
+    // TODO: Is a Duration too large (64 + 32 bits) for an object that will be created so often?
+    // Would it be better to use a u64 for microseconds?
+    // TODO: Is this just a monotonically increasing number, or is it a unix timestamp?
+    pub timestamp: std::time::Duration,
+    pub id: CanId,
+    pub channel: Channel,
+    pub data: [u8; 8],
+    pub data_length: u8,
+    pub extended: bool,
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/driver/mod.rs.html b/src/ag_iso_stack/driver/mod.rs.html new file mode 100644 index 0000000..ce39f68 --- /dev/null +++ b/src/ag_iso_stack/driver/mod.rs.html @@ -0,0 +1,51 @@ +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
+
// Copyright 2023 Raven Industries inc.
+
+//! CAN Driver layer
+//!
+//! This module defines:
+//! 1. An abstract `Driver` trait for different CAN drivers to implement
+//! 2. `Frame`, `Pgn`, `Address`, et al types
+
+mod address;
+mod can_id;
+mod driver;
+mod frame;
+mod pgn;
+
+#[cfg(feature = "socketcan")]
+mod socketcan;
+
+pub use address::Address;
+pub use can_id::{CanId, Priority, Type};
+pub use driver::{Driver, DriverCloseError, DriverOpenError, DriverReadError, DriverWriteError};
+pub use frame::{Channel, Frame};
+pub use pgn::Pgn;
+
+#[cfg(feature = "socketcan")]
+pub use self::socketcan::SocketcanDriver;
+
\ No newline at end of file diff --git a/src/ag_iso_stack/driver/pgn.rs.html b/src/ag_iso_stack/driver/pgn.rs.html new file mode 100644 index 0000000..5d16e5b --- /dev/null +++ b/src/ag_iso_stack/driver/pgn.rs.html @@ -0,0 +1,259 @@ +pgn.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
+
// Copyright 2023 Raven Industries inc.
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[repr(transparent)]
+pub struct Pgn(u32);
+
+impl Pgn {
+    /// A fake PGN used to denote a PGN that does not exist
+    pub const NULL: Pgn = Pgn(0xFFFFFFFF);
+
+    pub fn from_id(can_id: u32) -> Self {
+        const PDU2_FORMAT_MASK: u32 = 0x00F00000;
+        let raw_pgn = if (can_id & PDU2_FORMAT_MASK) < PDU2_FORMAT_MASK {
+            // point-to-point
+            (can_id >> 8) & 0x03FF00
+        } else {
+            // broadcast
+            (can_id >> 8) & 0x03FFFF
+        };
+        Pgn(raw_pgn)
+    }
+
+    pub fn from_raw(pgn: u32) -> Self {
+        Pgn(pgn)
+    }
+
+    #[inline]
+    pub fn is_broadcast(&self) -> bool {
+        !self.is_destination_specific()
+    }
+
+    #[inline]
+    pub fn is_destination_specific(&self) -> bool {
+        // PDU1 / destination specific PGNs have a PDU Format 0x00 - 0xEF
+        // PDU2 / broadcast PGNs have a PDU Format 0xF0 - 0xFF
+        self.pdu_format() <= 0xEF
+    }
+
+    #[inline]
+    pub fn is_proprietary(&self) -> bool {
+        self.pdu_format() == 0xEF
+    }
+
+    #[inline]
+    pub fn raw(&self) -> u32 {
+        self.0
+    }
+
+    #[inline]
+    pub fn pdu_specific(&self) -> u8 {
+        (self.raw() & 0x00FF) as u8
+    }
+
+    #[inline]
+    pub fn pdu_format(&self) -> u8 {
+        ((self.raw() & 0xFF00) >> 8) as u8
+    }
+
+    #[inline]
+    pub fn data_page(&self) -> u8 {
+        ((self.raw() & 0x10000) >> 16) as u8
+    }
+
+    #[inline]
+    pub fn extended_data_page(&self) -> u8 {
+        ((self.raw() & 0x20000) >> 17) as u8
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_from_id() {
+        let pgn = Pgn::from_id(0x18EF1CF5);
+        let expected = Pgn::from_raw(0x0EF00);
+        assert_eq!(pgn, expected);
+
+        let pgn = Pgn::from_id(0x18FF3F13);
+        let expected = Pgn::from_raw(0x0FF3F);
+        assert_eq!(pgn, expected);
+    }
+
+    #[test]
+    fn test_bitmath() {
+        let pgn = Pgn::from_raw(0x30000);
+        assert_eq!(pgn.data_page(), 0x01);
+        assert_eq!(pgn.extended_data_page(), 0x01);
+
+        let pgn = Pgn::from_raw(0x0FF00);
+        assert_eq!(pgn.pdu_format(), 0xFF);
+        assert_eq!(pgn.pdu_specific(), 0x00);
+
+        let pgn = Pgn::from_raw(0x000FF);
+        assert_eq!(pgn.pdu_format(), 0x00);
+        assert_eq!(pgn.pdu_specific(), 0xFF);
+    }
+
+    #[test]
+    fn test_p2p() {
+        let pgn = Pgn::from_raw(0x0EE00);
+        assert_eq!(pgn.is_destination_specific(), true);
+        let pgn = Pgn::from_raw(0x0EF00);
+        assert_eq!(pgn.is_destination_specific(), true);
+        let pgn = Pgn::from_raw(0x0F000);
+        assert_eq!(pgn.is_destination_specific(), false);
+        let pgn = Pgn::from_raw(0x0FEFF);
+        assert_eq!(pgn.is_destination_specific(), false);
+        let pgn = Pgn::from_raw(0x0FF00);
+        assert_eq!(pgn.is_destination_specific(), false);
+        let pgn = Pgn::from_raw(0x0FFFF);
+        assert_eq!(pgn.is_destination_specific(), false);
+        let pgn = Pgn::from_raw(0x10000);
+        assert_eq!(pgn.is_destination_specific(), true);
+        let pgn = Pgn::from_raw(0x1EE00);
+        assert_eq!(pgn.is_destination_specific(), true);
+        let pgn = Pgn::from_raw(0x1EF00);
+        assert_eq!(pgn.is_destination_specific(), true);
+        let pgn = Pgn::from_raw(0x1F000);
+        assert_eq!(pgn.is_destination_specific(), false);
+        let pgn = Pgn::from_raw(0x1FEFF);
+        assert_eq!(pgn.is_destination_specific(), false);
+        let pgn = Pgn::from_raw(0x1FF00);
+        assert_eq!(pgn.is_destination_specific(), false);
+        let pgn = Pgn::from_raw(0x1FFFF);
+        assert_eq!(pgn.is_destination_specific(), false);
+    }
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/driver/socketcan.rs.html b/src/ag_iso_stack/driver/socketcan.rs.html new file mode 100644 index 0000000..75259bd --- /dev/null +++ b/src/ag_iso_stack/driver/socketcan.rs.html @@ -0,0 +1,307 @@ +socketcan.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
+
// Copyright 2023 Raven Industries inc.
+use std::time::Instant;
+
+use socketcan::frame::{CanDataFrame, CanFrame, Frame};
+use socketcan::{CanSocket, EmbeddedFrame, ExtendedId, Id, Socket, StandardId};
+
+use crate::driver::{
+    CanId, Channel, Driver, DriverCloseError, DriverOpenError, DriverReadError, DriverWriteError,
+    Frame as InternalFrame, Type,
+};
+
+impl From<socketcan::Error> for DriverReadError {
+    fn from(e: socketcan::Error) -> DriverReadError {
+        match e {
+            socketcan::Error::Can(_) => DriverReadError::ErrorFrame(),
+            socketcan::Error::Io(e) => DriverReadError::IoError(e),
+        }
+    }
+}
+
+impl From<socketcan::Error> for DriverWriteError {
+    fn from(e: socketcan::Error) -> DriverWriteError {
+        match e {
+            socketcan::Error::Can(_) => DriverWriteError::BusError(),
+            socketcan::Error::Io(e) => DriverWriteError::IoError(e),
+        }
+    }
+}
+
+impl From<&InternalFrame> for socketcan::frame::CanDataFrame {
+    fn from(f: &InternalFrame) -> socketcan::frame::CanDataFrame {
+        let id = match f.id.type_() {
+            Type::Standard => Id::Standard(unsafe { StandardId::new_unchecked(f.id.raw() as u16) }),
+            Type::Extended => Id::Extended(unsafe { ExtendedId::new_unchecked(f.id.raw()) }),
+        };
+        CanDataFrame::new(id, &f.data[..f.data_length.min(8) as usize])
+            // guaranteed to not crash, because `f.data` is an [u8; 8]
+            .expect("Can frame had too much data")
+    }
+}
+
+enum SocketcanIface {
+    Name(String),
+    Index(u32),
+}
+
+/// A Linux socketcan [Driver]
+///
+/// Enabled with the optional `socketcan` feature
+pub struct SocketcanDriver {
+    iface: SocketcanIface,
+    sock: Option<CanSocket>,
+    opened_timestamp: Instant,
+}
+
+impl SocketcanDriver {
+    /// Create a socketcan driver with the given interface name. E.g., `can0`, or `vcan1`
+    pub fn new_by_name(if_name: &str) -> Self {
+        Self {
+            iface: SocketcanIface::Name(if_name.to_string()),
+            sock: None,
+            opened_timestamp: Instant::now(),
+        }
+    }
+
+    /// Create a socketcan driver with the given interface index
+    pub fn new_by_index(if_index: u32) -> Self {
+        Self {
+            iface: SocketcanIface::Index(if_index),
+            sock: None,
+            opened_timestamp: Instant::now(),
+        }
+    }
+
+    fn to_frame(&self, f: CanFrame) -> InternalFrame {
+        match f {
+            CanFrame::Remote(_r) => todo!("Remote frames unsupported yet"),
+            CanFrame::Error(_e) => todo!("Error frames unsupported yet"),
+            CanFrame::Data(f) => {
+                let timestamp = self.opened_timestamp.elapsed();
+                let raw_id = f.raw_id();
+                let extended = f.is_extended();
+                let frame_type = if extended {
+                    Type::Extended
+                } else {
+                    Type::Standard
+                };
+
+                let id = CanId::new(raw_id, frame_type);
+                // TODO: The Driver trait doesn't know anything about Channels yet.
+                //
+                // The channel exists so that we can tie Frames and CANMessages back to the network
+                // manager they originated from. This channel value should be passed to the Driver
+                // when it's created (or opened?)
+                let channel = Channel::default();
+                let mut data = [0; 8];
+                let data_length = f.dlc().min(8);
+                data[..data_length].copy_from_slice(f.data());
+                let data_length = data_length as u8;
+
+                InternalFrame {
+                    timestamp,
+                    id,
+                    channel,
+                    data,
+                    data_length,
+                    extended,
+                }
+            }
+        }
+    }
+}
+
+impl Driver for SocketcanDriver {
+    fn is_valid(&self) -> bool {
+        self.sock.is_some()
+    }
+    fn open(&mut self) -> Result<(), DriverOpenError> {
+        match &self.iface {
+            SocketcanIface::Name(s) => self.sock = Some(CanSocket::open(s)?),
+            SocketcanIface::Index(i) => self.sock = Some(CanSocket::open_iface(*i)?),
+        }
+        self.opened_timestamp = Instant::now();
+
+        // NOTE: unwrap() is safe, because we return a DriverOpenError if we fail to create it.
+        self.sock.as_ref().unwrap().set_nonblocking(true)?;
+        Ok(())
+    }
+    fn close(&mut self) -> Result<(), DriverCloseError> {
+        self.sock = None;
+        Ok(())
+    }
+
+    /// Read a frame from the driver, if possible
+    ///
+    /// The timestamp on the frame is the duration since [`open`](Self::open) was last called.
+    fn read_nonblocking(&mut self, frame: &mut InternalFrame) -> Result<(), DriverReadError> {
+        let Some(sock) = self.sock.as_mut() else {
+            return Err(DriverReadError::DriverClosed);
+        };
+        let socketcan_frame = sock.read_frame()?;
+        *frame = self.to_frame(socketcan_frame);
+        Ok(())
+    }
+    fn write_nonblocking(&mut self, frame: &InternalFrame) -> Result<(), DriverWriteError> {
+        let Some(sock) = self.sock.as_mut() else {
+            return Err(DriverWriteError::DriverClosed);
+        };
+        let socketcan_frame: socketcan::frame::CanDataFrame = frame.into();
+        sock.write_frame(&socketcan_frame)?;
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/lib.rs.html b/src/ag_iso_stack/lib.rs.html new file mode 100644 index 0000000..62fe312 --- /dev/null +++ b/src/ag_iso_stack/lib.rs.html @@ -0,0 +1,15 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+
// Copyright 2023 Raven Industries inc.
+#![allow(clippy::bool_assert_comparison)]
+#![allow(clippy::needless_return)]
+#![allow(clippy::module_inception)]
+
+pub mod driver;
+pub mod network_management;
+
\ No newline at end of file diff --git a/src/ag_iso_stack/network_management/can_message.rs.html b/src/ag_iso_stack/network_management/can_message.rs.html new file mode 100644 index 0000000..377b24b --- /dev/null +++ b/src/ag_iso_stack/network_management/can_message.rs.html @@ -0,0 +1,75 @@ +can_message.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
+
// Copyright 2023 Raven Industries inc.
+use super::name::NAME;
+use crate::driver::CanId;
+
+pub struct CANMessage {
+    data: Vec<u8>,
+    identifier: CanId,
+    source_name: NAME,
+    destination_name: NAME,
+}
+
+impl CANMessage {
+    pub(super) fn new(data: Vec<u8>, identifier: CanId) -> CANMessage {
+        CANMessage {
+            data,
+            identifier,
+            source_name: NAME::default(),
+            destination_name: NAME::default(),
+        }
+    }
+
+    pub fn get_data(&self) -> &[u8] {
+        self.data.as_slice()
+    }
+
+    pub fn get_identifier(&self) -> CanId {
+        self.identifier
+    }
+
+    pub fn get_source_name(&self) -> NAME {
+        self.source_name
+    }
+
+    pub fn get_destination_name(&self) -> NAME {
+        self.destination_name
+    }
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/network_management/common_parameter_group_numbers.rs.html b/src/ag_iso_stack/network_management/common_parameter_group_numbers.rs.html new file mode 100644 index 0000000..06aa145 --- /dev/null +++ b/src/ag_iso_stack/network_management/common_parameter_group_numbers.rs.html @@ -0,0 +1,125 @@ +common_parameter_group_numbers.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
+
// Copyright 2023 Raven Industries inc.
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum CommonParameterGroupNumbers {
+    TractorImplementManagementServerToTimClient = 0x002300,
+    TractorImplementManagementClientToTimServer = 0x002400,
+    AuthenticationClientToAuthenticationServer = 0x006F00,
+    AuthenticationServerToAuthenticationClient = 0x007000,
+    NameManagement = 0x009300,
+    GuidanceMachineStatus = 0x00AC00,
+    GuidanceSystemCommand = 0x00AD00,
+    ExtendedTransportProtocolData = 0x00C700,
+    ExtendedTransportProtocolCommand = 0x00C800,
+    RequestForRepetitionRate = 0x00CC00,
+    BinaryDataTransfer = 0x00D700,
+    MemoryAccessResponse = 0x00D800,
+    MemoryAccessRequest = 0x00D900,
+    StopStartBroadcast = 0x00DF00,
+    VirtualTerminalToNode = 0x00E600,
+    NodeToVirtualTerminal = 0x00E700,
+    Acknowledgement = 0x00E800,
+    ParameterGroupNumberRequest = 0x00EA00,
+    TransportProtocolData = 0x00EB00,
+    TransportProtocolCommand = 0x00EC00,
+    AddressClaim = 0x00EE00,
+    ProprietaryA = 0x00EF00,
+    ElectronicEngineController2 = 0x00F003,
+    ElectronicEngineController1 = 0x00F004,
+    HeartbeatMessage = 0x00F0E4,
+    ProductIdentification = 0x00FC8D,
+    ControlFunctionFunctionalities = 0x00FC8E,
+    DiagnosticProtocol = 0x00FD32,
+    IsobusComplianceCertificationMessage = 0x00FD42,
+    EcuIdentificationInformation = 0x00FDC5,
+    WorkingSetMaster = 0x00FE0D,
+    ResponseForRepetitionRate = 0x00FE0E,
+    MaintainPower = 0x00FE47,
+    WheelBasedSpeedAndDistance = 0x00FE48,
+    GroundBasedSpeedAndDistance = 0x00FE49,
+    ActiveDiagnosticTroubleCodes = 0x00FECA,
+    PreviouslyActiveDiagnosticTroubleCodes = 0x00FECB,
+    DiagnosticDataClearResetOfPreviouslyActiveDtcs = 0x00FECC,
+    FreezeFrameParameters = 0x00FECD,
+    DiagnosticDataClearResetForActiveDtcs = 0x00FED3,
+    CommandedAddress = 0x00FED8,
+    SoftwareIdentification = 0x00FEDA,
+    TimeDate = 0x00FEE6,
+    EngineTemperature1 = 0x00FEEE,
+    CruiseControlVehicleSpeed1 = 0x00FEF1,
+    IntakeExhaustConditions1 = 0x00FEF6,
+    NmeaAttitude = 0x01F119,
+    NmeaCogSogRapidUpdate = 0x01F802,
+    NmeaPositionDeltaHighPrecisionRapidUpdate = 0x01F803,
+    NmeaAltitudeDeltaHighPrecisionRapidUpdate = 0x01F804,
+    NmeaGnssPositionData = 0x01F805,
+    NmeaTimeDate = 0x01F809,
+    NmeaGnssDops = 0x01FA03,
+    NmeaGnssSatsInView = 0x01FA04,
+    NmeaGnssPseudoRangeNoiseStatistics = 0x01FA06,
+    NmeaGnssPseudoRangeErrorStatistics = 0x01FA0B,
+    AllowAll = 0xFFFFFF,
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/network_management/control_function.rs.html b/src/ag_iso_stack/network_management/control_function.rs.html new file mode 100644 index 0000000..fb406dd --- /dev/null +++ b/src/ag_iso_stack/network_management/control_function.rs.html @@ -0,0 +1,517 @@ +control_function.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
+
// Copyright 2023 Raven Industries inc.
+use crate::driver::Address;
+use crate::network_management::name::NAME;
+use rand::Rng;
+use std::cell::RefCell;
+use std::rc::Rc;
+use std::time::{Duration, Instant};
+
+use super::network_manager::{MessageQueuePriority, NetworkManager};
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub enum AddressClaimingState {
+    /// Address claiming is uninitialized
+    None,
+    /// State machine is waiting for the random delay time                       
+    WaitForClaim,
+    /// State machine is sending the request for address claim                
+    SendRequestForClaim,
+    /// State machine is waiting for the address claim contention period         
+    WaitForRequestContentionPeriod,
+    /// State machine is claiming the preferred address
+    SendPreferredAddressClaim,
+    /// State machine is contending the preferred address  
+    ContendForPreferredAddress,
+    /// State machine is claiming an address   
+    SendArbitraryAddressClaim,
+    /// An ECU requested address claim, inform the bus of our current address    
+    SendReclaimAddressOnRequest,
+    /// State machine could not claim an address
+    UnableToClaim,
+    /// Address claiming is complete and we have an address     
+    AddressClaimingComplete,
+}
+
+pub struct AddressClaimingData {
+    state: AddressClaimingState,
+    name: NAME,
+    timestamp: Option<Instant>,
+    preferred_address: Address,
+    random_delay: u8,
+    enabled: bool,
+}
+
+pub enum ControlFunction {
+    Internal {
+        address_claim_data: AddressClaimingData,
+    },
+    External {
+        name: NAME,
+    },
+}
+
+impl ControlFunction {
+    pub fn new_internal_control_function(
+        name: NAME,
+        preferred_address: Address,
+        enabled: bool,
+        network: &mut NetworkManager,
+    ) -> Rc<RefCell<Self>> {
+        let cf = Rc::new(RefCell::new(ControlFunction::Internal {
+            address_claim_data: AddressClaimingData::new(name, preferred_address, enabled),
+        }));
+        network.on_new_internal_control_function(cf.clone());
+        cf
+    }
+
+    pub fn get_name(&self) -> NAME {
+        match self {
+            ControlFunction::Internal { address_claim_data } => address_claim_data.get_name(),
+            ControlFunction::External { name } => *name,
+        }
+    }
+}
+
+impl AddressClaimingState {
+    pub(super) fn new() -> Self {
+        Self::None
+    }
+
+    pub(super) fn update_state_none(_claim_to_process: &AddressClaimingData) -> Self {
+        AddressClaimingState::WaitForClaim
+    }
+
+    pub(super) fn update_state_wait_for_claim(claim_to_process: &AddressClaimingData) -> Self {
+        if Instant::now().duration_since(claim_to_process.get_timestamp().unwrap())
+            > Duration::from_millis(claim_to_process.get_random_delay() as u64)
+        {
+            AddressClaimingState::SendRequestForClaim
+        } else {
+            AddressClaimingState::WaitForClaim
+        }
+    }
+
+    pub(super) fn update_state_send_request_for_claim(network: &mut NetworkManager) -> Self {
+        network.enqueue_can_message(
+            NetworkManager::construct_request_for_address_claim(),
+            MessageQueuePriority::High,
+        );
+        AddressClaimingState::WaitForRequestContentionPeriod
+    }
+
+    pub(super) fn update_state_wait_for_request_contention(
+        claim_to_process: &AddressClaimingData,
+        network: &mut NetworkManager,
+    ) -> Self {
+        let contention_time_ms: u64 = 250;
+
+        if Instant::now().duration_since(claim_to_process.get_timestamp().unwrap())
+            > Duration::from_millis(claim_to_process.get_random_delay() as u64 + contention_time_ms)
+        {
+            let is_device_at_our_address =
+                network.get_control_function_by_address(claim_to_process.get_preferred_address());
+            let is_valid_device: bool = is_device_at_our_address.is_some();
+
+            if is_valid_device {
+                let preferred_address_name: u64 =
+                    match *is_device_at_our_address.as_ref().unwrap().clone().borrow() {
+                        ControlFunction::External { name } => name.into(),
+                        ControlFunction::Internal {
+                            address_claim_data: _,
+                        } => claim_to_process.get_name().into(),
+                    };
+
+                if (!claim_to_process.get_name().get_self_configurable_address()
+                    && preferred_address_name > claim_to_process.get_name().into())
+                    || <NAME as Into<u64>>::into(NAME::default()) == preferred_address_name
+                {
+                    // Either our preferred address is free, this is the best case, or:
+                    // Our address is not free, but we cannot be at an arbitrary address, and the address can be stolen by us
+                    AddressClaimingState::SendPreferredAddressClaim
+                } else if !claim_to_process.get_name().get_self_configurable_address() {
+                    // We cannot claim because we cannot tolerate an arbitrary address, and the CF at that spot wins due to its lower ISONAME
+                    AddressClaimingState::UnableToClaim
+                } else {
+                    // We will move to another address if whoever is in our spot has a lower NAME
+                    if preferred_address_name < claim_to_process.get_name().into() {
+                        // We must scan the address space and move to a free address
+                        AddressClaimingState::SendArbitraryAddressClaim
+                    } else {
+                        // Our address claim wins because it's lower than the device that's in our preferred spot
+                        AddressClaimingState::SendPreferredAddressClaim
+                    }
+                }
+            } else {
+                AddressClaimingState::SendPreferredAddressClaim
+            }
+        } else {
+            AddressClaimingState::WaitForRequestContentionPeriod
+        }
+    }
+
+    pub(super) fn update_state_send_preferred_address_claim(
+        claim_to_process: &AddressClaimingData,
+        network: &mut NetworkManager,
+    ) -> Self {
+        network.enqueue_can_message(
+            NetworkManager::construct_address_claim(
+                claim_to_process.get_preferred_address(),
+                claim_to_process.get_name(),
+            ),
+            MessageQueuePriority::High,
+        );
+        AddressClaimingState::AddressClaimingComplete
+    }
+
+    pub(super) fn update_state_send_arbitrary_address_claim(
+        claim_to_process: &AddressClaimingData,
+        network: &mut NetworkManager,
+    ) -> Self {
+        let next_address = network.get_next_free_arbitrary_address();
+
+        if Address::NULL != next_address {
+            // Found an address we can use
+            network.enqueue_can_message(
+                NetworkManager::construct_address_claim(next_address, claim_to_process.get_name()),
+                MessageQueuePriority::High,
+            );
+            return AddressClaimingState::AddressClaimingComplete;
+        }
+        AddressClaimingState::UnableToClaim
+    }
+}
+
+impl Default for AddressClaimingState {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl AddressClaimingData {
+    pub fn new(name: NAME, preferred_address: Address, enabled: bool) -> AddressClaimingData {
+        AddressClaimingData {
+            state: AddressClaimingState::None,
+            name,
+            timestamp: None,
+            preferred_address,
+            random_delay: AddressClaimingData::generate_random_delay(),
+            enabled,
+        }
+    }
+
+    pub fn get_enabled(&self) -> bool {
+        self.enabled
+    }
+
+    pub fn set_enabled(&mut self, enable: bool) {
+        self.enabled = enable;
+
+        if !enable {
+            self.timestamp = None;
+            self.state = AddressClaimingState::None;
+        }
+    }
+
+    pub fn get_preferred_address(&self) -> Address {
+        self.preferred_address
+    }
+
+    pub(super) fn set_preferred_address(&mut self, new_address: Address) {
+        self.preferred_address = new_address;
+    }
+
+    pub fn get_state(&self) -> AddressClaimingState {
+        self.state
+    }
+
+    pub(super) fn set_state(&mut self, new_state: AddressClaimingState) {
+        self.state = new_state;
+    }
+
+    pub fn get_name(&self) -> NAME {
+        self.name
+    }
+
+    pub fn set_name(&mut self, new_name: NAME) {
+        if self.name != new_name {
+            self.state = AddressClaimingState::None; // Name changed, state no longer valid
+        }
+        self.name = new_name;
+    }
+
+    pub fn get_timestamp(&self) -> Option<Instant> {
+        self.timestamp
+    }
+
+    pub(super) fn set_timestamp(&mut self, new_timestamp: Option<Instant>) {
+        self.timestamp = new_timestamp;
+    }
+
+    pub(super) fn get_random_delay(&self) -> u8 {
+        self.random_delay
+    }
+
+    pub(super) fn generate_random_delay() -> u8 {
+        let mut rng: rand::rngs::ThreadRng = rand::thread_rng();
+        (rng.gen_range(0..255) as f32 * 0.6_f32) as u8
+    }
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/network_management/mod.rs.html b/src/ag_iso_stack/network_management/mod.rs.html new file mode 100644 index 0000000..7f77a1b --- /dev/null +++ b/src/ag_iso_stack/network_management/mod.rs.html @@ -0,0 +1,13 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+
// Copyright 2023 Raven Industries inc.
+pub mod can_message;
+pub mod common_parameter_group_numbers;
+pub mod control_function;
+pub mod name;
+pub mod network_manager;
+
\ No newline at end of file diff --git a/src/ag_iso_stack/network_management/name.rs.html b/src/ag_iso_stack/network_management/name.rs.html new file mode 100644 index 0000000..5269d08 --- /dev/null +++ b/src/ag_iso_stack/network_management/name.rs.html @@ -0,0 +1,909 @@ +name.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
+
// Copyright 2023 Raven Industries inc.
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub enum NameField {
+    IdentityNumber(u32),
+    ShortIdentityNumber(u16),
+    ExtendedIdentityNumber(u8),
+    ManufacturerCode(u16),
+    EcuInstance(u8),
+    FunctionInstance(u8),
+    Function(u8),
+    DeviceClass(u8),
+    DeviceClassInstance(u8),
+    IndustryGroup(u8),
+    SelfConfigurableAddress(bool),
+}
+
+#[derive(Copy, Clone, PartialEq)]
+pub struct NAME {
+    raw_name: u64,
+}
+
+impl NAME {
+    pub fn new(raw_name: u64) -> Self {
+        Self { raw_name }
+    }
+
+    pub fn builder() -> NameBuilder {
+        NameBuilder::default()
+    }
+
+    pub fn has_field_value(&self, field_value: NameField) -> bool {
+        *self != NAME::default()
+            && match field_value {
+                NameField::IdentityNumber(value) => self.get_identity_number() == value,
+                NameField::ShortIdentityNumber(value) => self.get_short_identity_number() == value,
+                NameField::ExtendedIdentityNumber(value) => {
+                    self.get_extended_identity_number() == value
+                }
+                NameField::ManufacturerCode(value) => self.get_manufacturer_code() == value,
+                NameField::EcuInstance(value) => self.get_ecu_instance() == value,
+                NameField::FunctionInstance(value) => self.get_function_instance() == value,
+                NameField::Function(value) => self.get_function() == value,
+                NameField::DeviceClass(value) => self.get_device_class() == value,
+                NameField::DeviceClassInstance(value) => self.get_device_class_instance() == value,
+                NameField::IndustryGroup(value) => self.get_industry_group() == value,
+                NameField::SelfConfigurableAddress(value) => {
+                    self.get_self_configurable_address() == value
+                }
+            }
+    }
+
+    pub fn has_field_values(&self, name_fields: &[NameField]) -> bool {
+        /// A helper function to get the index of a field
+        /// This is used to set the bits in a mask to check if all supplied fields are satisfied
+        fn get_index(field: &NameField) -> u8 {
+            match field {
+                NameField::IdentityNumber(_) => 0,
+                NameField::ShortIdentityNumber(_) => 1,
+                NameField::ExtendedIdentityNumber(_) => 2,
+                NameField::ManufacturerCode(_) => 3,
+                NameField::EcuInstance(_) => 4,
+                NameField::FunctionInstance(_) => 5,
+                NameField::Function(_) => 6,
+                NameField::DeviceClass(_) => 7,
+                NameField::DeviceClassInstance(_) => 8,
+                NameField::IndustryGroup(_) => 9,
+                NameField::SelfConfigurableAddress(_) => 10,
+            }
+        }
+
+        // Make a mask of all the fields present in the supplied array
+        let fields_present = name_fields.iter().fold(0_u16, |acc, name_field| {
+            return acc | 1 << get_index(name_field);
+        });
+        // Make a mask of all the fields satisfied in the supplied array
+        let fields_satisfied = name_fields.iter().fold(0_u16, |acc, name_field| {
+            if self.has_field_value(*name_field) {
+                return acc | 1 << get_index(name_field);
+            } else {
+                return acc;
+            }
+        });
+        return fields_satisfied == fields_present;
+    }
+
+    pub fn get_device_class(&self) -> u8 {
+        ((self.raw_name >> 49) & 0x7F) as u8
+    }
+
+    pub fn set_device_class(&mut self, device_class: u8) {
+        self.raw_name &= !0x00FE000000000000_u64;
+        self.raw_name |= ((device_class & 0x7F) as u64) << 49;
+    }
+
+    pub fn get_device_class_instance(&self) -> u8 {
+        ((self.raw_name >> 56) & 0x0F) as u8
+    }
+
+    pub fn set_device_class_instance(&mut self, device_class_instance: u8) {
+        self.raw_name &= !0x0F00000000000000;
+        self.raw_name |= ((device_class_instance & 0x0F) as u64) << 56;
+    }
+
+    pub fn get_ecu_instance(&self) -> u8 {
+        ((self.raw_name >> 32) & 0x07) as u8
+    }
+
+    pub fn set_ecu_instance(&mut self, ecu_instance: u8) {
+        self.raw_name &= !0x0000000700000000;
+        self.raw_name |= ((ecu_instance & 0x07) as u64) << 32;
+    }
+
+    pub fn get_extended_identity_number(&self) -> u8 {
+        ((self.raw_name >> 16) & 0x1F) as u8
+    }
+
+    pub fn set_extended_identity_number(&mut self, extended_identity_number: u8) {
+        self.raw_name &= !0x00000000001F0000;
+        self.raw_name |= ((extended_identity_number & 0x1F) as u64) << 16;
+    }
+
+    pub fn get_function(&self) -> u8 {
+        ((self.raw_name >> 40) & 0xFF) as u8
+    }
+
+    pub fn set_function(&mut self, function: u8) {
+        self.raw_name &= !0x0000FF0000000000;
+        self.raw_name |= (function as u64) << 40;
+    }
+
+    pub fn get_function_instance(&self) -> u8 {
+        ((self.raw_name >> 35) & 0x1F) as u8
+    }
+
+    pub fn set_function_instance(&mut self, function: u8) {
+        self.raw_name &= !0x000000F800000000;
+        self.raw_name |= ((function & 0x1F) as u64) << 35;
+    }
+
+    pub fn get_identity_number(&self) -> u32 {
+        (self.raw_name & 0x001FFFFF) as u32
+    }
+
+    pub fn set_identity_number(&mut self, identity_number: u32) {
+        self.raw_name &= !0x00000000001FFFFF;
+        self.raw_name |= (identity_number & 0x00000000001FFFFF) as u64;
+    }
+
+    pub fn get_industry_group(&self) -> u8 {
+        ((self.raw_name >> 60) & 0x07) as u8
+    }
+
+    pub fn set_industry_group(&mut self, industry_group: u8) {
+        self.raw_name &= !0x7000000000000000;
+        self.raw_name |= ((industry_group & 0x07) as u64) << 60;
+    }
+
+    pub fn get_manufacturer_code(&self) -> u16 {
+        ((self.raw_name >> 21) & 0x07FF) as u16
+    }
+
+    pub fn set_manufacturer_code(&mut self, manufacturer_code: u16) {
+        self.raw_name &= !0x00000000FFE00000;
+        self.raw_name |= ((manufacturer_code & 0x07FF) as u64) << 21;
+    }
+
+    pub fn get_self_configurable_address(&self) -> bool {
+        (self.raw_name >> 63) != 0
+    }
+
+    pub fn set_self_configurable_address(&mut self, self_configurable_address: bool) {
+        self.raw_name &= !0x8000000000000000;
+        self.raw_name |= (self_configurable_address as u64) << 63;
+    }
+
+    pub fn get_short_identity_number(&self) -> u16 {
+        (self.raw_name & 0x0000FFFF) as u16
+    }
+
+    pub fn set_short_identity_number(&mut self, short_identity_number: u16) {
+        self.raw_name &= !0x000000000000FFFF;
+        self.raw_name |= short_identity_number as u64;
+    }
+}
+
+impl Default for NAME {
+    fn default() -> Self {
+        Self {
+            raw_name: 0xFFFFFFFFFFFFFFFF,
+        }
+    }
+}
+
+impl From<NAME> for u64 {
+    fn from(name: NAME) -> Self {
+        name.raw_name
+    }
+}
+
+#[derive(Default)]
+pub struct NameBuilder {
+    self_configurable_address: bool,
+    industry_group: u8,
+    device_class_instance: u8,
+    device_class: u8,
+    function_code: u8,
+    function_instance: u8,
+    ecu_instance: u8,
+    manufacturer_code: u16,
+    identity_number: u32,
+}
+
+impl NameBuilder {
+    pub fn new() -> NameBuilder {
+        NameBuilder::default()
+    }
+
+    pub fn build(&self) -> NAME {
+        NAME {
+            raw_name: (self.self_configurable_address as u64) << 63
+                | (self.industry_group as u64 & 0x7) << 60
+                | (self.device_class_instance as u64 & 0xF) << 56
+                | (self.device_class as u64 & 0x7F) << 49
+                | (self.function_code as u64 & 0xFF) << 40
+                | (self.function_instance as u64 & 0x1F) << 35
+                | (self.ecu_instance as u64 & 0x7) << 32
+                | (self.manufacturer_code as u64 & 0x7FF) << 21
+                | self.identity_number as u64 & 0x1FFFFF,
+        }
+    }
+
+    pub fn self_configurable_address(&mut self, value: impl Into<bool>) -> &mut NameBuilder {
+        self.self_configurable_address = value.into();
+        self
+    }
+    pub fn industry_group(&mut self, value: impl Into<u8>) -> &mut NameBuilder {
+        self.industry_group = value.into();
+        self
+    }
+    pub fn device_class_instance(&mut self, value: impl Into<u8>) -> &mut NameBuilder {
+        self.device_class_instance = value.into();
+        self
+    }
+    pub fn device_class(&mut self, value: impl Into<u8>) -> &mut NameBuilder {
+        self.device_class = value.into();
+        self
+    }
+    pub fn function_code(&mut self, value: impl Into<u8>) -> &mut NameBuilder {
+        self.function_code = value.into();
+        self
+    }
+    pub fn function_instance(&mut self, value: impl Into<u8>) -> &mut NameBuilder {
+        self.function_instance = value.into();
+        self
+    }
+    pub fn ecu_instance(&mut self, value: impl Into<u8>) -> &mut NameBuilder {
+        self.ecu_instance = value.into();
+        self
+    }
+    pub fn manufacturer_code(&mut self, value: impl Into<u16>) -> &mut NameBuilder {
+        self.manufacturer_code = value.into();
+        self
+    }
+    pub fn identity_number(&mut self, value: impl Into<u32>) -> &mut NameBuilder {
+        self.identity_number = value.into();
+        self
+    }
+}
+
+impl From<NAME> for NameBuilder {
+    fn from(value: NAME) -> Self {
+        let value: u64 = value.into();
+        NameBuilder {
+            self_configurable_address: (value >> 63) != 0,
+            industry_group: (value >> 60 & 0x7) as u8,
+            device_class_instance: (value >> 56 & 0xF) as u8,
+            device_class: (value >> 49 & 0x7F) as u8,
+            function_code: (value >> 40 & 0xFF) as u8,
+            function_instance: (value >> 35 & 0x1F) as u8,
+            ecu_instance: (value >> 32 & 0x7) as u8,
+            manufacturer_code: (value >> 21 & 0x7FF) as u16,
+            identity_number: (value & 0x1FFFFF) as u32,
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_name_properties() {
+        let mut name_under_test = NAME::new(0);
+
+        name_under_test.set_self_configurable_address(true);
+        name_under_test.set_industry_group(1);
+        name_under_test.set_device_class(2);
+        name_under_test.set_function(3);
+        name_under_test.set_identity_number(4);
+        name_under_test.set_ecu_instance(5);
+        name_under_test.set_function_instance(6);
+        name_under_test.set_device_class_instance(7);
+        name_under_test.set_manufacturer_code(8);
+
+        assert_eq!(true, name_under_test.get_self_configurable_address());
+        assert_eq!(1, name_under_test.get_industry_group());
+        assert_eq!(2, name_under_test.get_device_class());
+        assert_eq!(3, name_under_test.get_function());
+        assert_eq!(4, name_under_test.get_identity_number());
+        assert_eq!(5, name_under_test.get_ecu_instance());
+        assert_eq!(6, name_under_test.get_function_instance());
+        assert_eq!(7, name_under_test.get_device_class_instance());
+        assert_eq!(8, name_under_test.get_manufacturer_code());
+        assert_eq!(0, name_under_test.get_extended_identity_number());
+        assert_eq!(4, name_under_test.get_short_identity_number());
+        assert_eq!(10881826125818888196_u64, name_under_test.raw_name);
+    }
+
+    #[test]
+    fn test_name_builder() {
+        let name_under_test = NAME::builder()
+            .identity_number(4_u32)
+            .manufacturer_code(8_u16)
+            .ecu_instance(5)
+            .function_instance(6)
+            .function_code(3)
+            .device_class(2)
+            .device_class_instance(7)
+            .industry_group(1)
+            .self_configurable_address(true)
+            .build();
+
+        assert_eq!(10881826125818888196_u64, name_under_test.into());
+    }
+
+    #[test]
+    fn test_out_of_range_properties() {
+        let mut name_under_test = NAME::new(0);
+
+        name_under_test.set_industry_group(8);
+        name_under_test.set_device_class_instance(16);
+        name_under_test.set_device_class(128);
+        name_under_test.set_identity_number(2097152);
+        name_under_test.set_ecu_instance(8);
+        name_under_test.set_function_instance(32);
+        name_under_test.set_manufacturer_code(2048);
+
+        assert_ne!(name_under_test.get_industry_group(), 8);
+        assert_ne!(name_under_test.get_device_class_instance(), 16);
+        assert_ne!(name_under_test.get_device_class(), 128);
+        assert_ne!(name_under_test.get_identity_number(), 2097151);
+        assert_ne!(name_under_test.get_ecu_instance(), 8);
+        assert_ne!(name_under_test.get_function_instance(), 32);
+        assert_ne!(name_under_test.get_manufacturer_code(), 2048);
+    }
+
+    #[test]
+    fn test_name_equality() {
+        let test_value: u64 = 10376445291390828545;
+        let name_under_test1 = NAME::new(test_value);
+        let name_under_test2 = NAME::new(test_value);
+
+        assert_eq!(test_value, name_under_test1.raw_name);
+        assert_eq!(name_under_test1.raw_name, name_under_test2.raw_name);
+    }
+
+    #[test]
+    fn test_filter_matching() {
+        let mut test_name = NAME::new(0);
+        let mut filters_to_test = Vec::new();
+
+        let identity_number_filter = NameField::IdentityNumber(1);
+        filters_to_test.push(identity_number_filter);
+        assert_eq!(false, test_name.has_field_value(identity_number_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_identity_number(1);
+        assert_eq!(true, test_name.has_field_value(identity_number_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let manufacturer_number_filter = NameField::ManufacturerCode(2);
+        filters_to_test.push(manufacturer_number_filter);
+        assert_eq!(false, test_name.has_field_value(manufacturer_number_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_manufacturer_code(2);
+        assert_eq!(true, test_name.has_field_value(manufacturer_number_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let ecu_instance_filter = NameField::EcuInstance(3);
+        filters_to_test.push(ecu_instance_filter);
+        assert_eq!(false, test_name.has_field_value(ecu_instance_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_ecu_instance(3);
+        assert_eq!(true, test_name.has_field_value(ecu_instance_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let function_instance_filter = NameField::FunctionInstance(4);
+        filters_to_test.push(function_instance_filter);
+        assert_eq!(false, test_name.has_field_value(function_instance_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_function_instance(4);
+        assert_eq!(true, test_name.has_field_value(function_instance_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let function_filter = NameField::Function(5);
+        filters_to_test.push(function_filter);
+        assert_eq!(false, test_name.has_field_value(function_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_function(5);
+        assert_eq!(true, test_name.has_field_value(function_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let device_class_filter = NameField::DeviceClass(6);
+        filters_to_test.push(device_class_filter);
+        assert_eq!(false, test_name.has_field_value(device_class_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_device_class(6);
+        assert_eq!(true, test_name.has_field_value(device_class_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let industry_group_filter = NameField::IndustryGroup(7);
+        filters_to_test.push(industry_group_filter);
+        assert_eq!(false, test_name.has_field_value(industry_group_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_industry_group(7);
+        assert_eq!(true, test_name.has_field_value(industry_group_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let device_class_inst_filter = NameField::DeviceClassInstance(8);
+        filters_to_test.push(device_class_inst_filter);
+        assert_eq!(false, test_name.has_field_value(device_class_inst_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_device_class_instance(8);
+        assert_eq!(true, test_name.has_field_value(device_class_inst_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+
+        let self_config_address_filter = NameField::SelfConfigurableAddress(true);
+        filters_to_test.push(self_config_address_filter);
+        assert_eq!(false, test_name.has_field_value(self_config_address_filter));
+        assert_eq!(false, test_name.has_field_values(&filters_to_test));
+
+        test_name.set_self_configurable_address(true);
+        assert_eq!(true, test_name.has_field_value(self_config_address_filter));
+        assert_eq!(true, test_name.has_field_values(&filters_to_test));
+    }
+}
+
\ No newline at end of file diff --git a/src/ag_iso_stack/network_management/network_manager.rs.html b/src/ag_iso_stack/network_management/network_manager.rs.html new file mode 100644 index 0000000..eed117f --- /dev/null +++ b/src/ag_iso_stack/network_management/network_manager.rs.html @@ -0,0 +1,727 @@ +network_manager.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
+
// Copyright 2023 Raven Industries inc.
+use std::time::Instant;
+
+use super::control_function::{AddressClaimingState, ControlFunction};
+use crate::driver::{Address, CanId, Pgn, Priority};
+use crate::network_management::can_message::CANMessage;
+use crate::network_management::common_parameter_group_numbers::CommonParameterGroupNumbers;
+use crate::network_management::name::NAME;
+use std::cell::RefCell;
+use std::collections::VecDeque;
+use std::rc::Rc;
+
+#[derive(Debug, Clone, Copy)]
+pub(super) enum MessageQueuePriority {
+    /// High priority messages are always sent to the driver before normal ones
+    High,
+    /// Normal messages are sent to the driver when no high priority messages are in the queue (todo)
+    Normal,
+}
+
+#[derive(Debug, Clone, Copy)]
+pub enum CANTransmitState {
+    /// Used to describe that a CAN message was accepted by the CAN stack to be sent
+    Success,
+    /// Used to describe that a CAN message was not accepted by the stack and will not be sent
+    Fail,
+}
+
+pub struct NetworkManager {
+    control_function_table: [Option<Rc<RefCell<ControlFunction>>>; 253],
+    inactive_control_functions: Vec<Rc<RefCell<ControlFunction>>>,
+    address_claim_state_machines: Vec<Rc<RefCell<ControlFunction>>>,
+    high_priority_can_message_tx_queue: VecDeque<CANMessage>,
+    normal_priority_can_message_tx_queue: VecDeque<CANMessage>,
+    receive_message_queue: VecDeque<CANMessage>,
+}
+
+impl NetworkManager {
+    pub fn new() -> Self {
+        Self {
+            control_function_table: std::array::from_fn(|_| None),
+            inactive_control_functions: Vec::new(),
+            address_claim_state_machines: Vec::new(),
+            high_priority_can_message_tx_queue: VecDeque::new(),
+            normal_priority_can_message_tx_queue: VecDeque::new(),
+            receive_message_queue: VecDeque::new(),
+        }
+    }
+
+    pub fn get_control_function_by_address(
+        &self,
+        address: Address,
+    ) -> &Option<Rc<RefCell<ControlFunction>>> {
+        &self.control_function_table[address.0 as usize]
+    }
+
+    pub fn get_control_function_address_by_name(&self, name: NAME) -> Address {
+        for (i, cf) in self.control_function_table.iter().enumerate() {
+            if let Some(extant_cf) = cf {
+                if extant_cf.borrow().get_name() == name {
+                    return Address(i as u8);
+                }
+            }
+        }
+        Address::NULL
+    }
+
+    pub(super) fn on_new_internal_control_function(
+        &mut self,
+        new_cf: Rc<RefCell<ControlFunction>>,
+    ) {
+        self.inactive_control_functions.push(new_cf.clone());
+        self.address_claim_state_machines.push(new_cf);
+    }
+
+    pub(super) fn get_next_free_arbitrary_address(&self) -> Address {
+        for address in 129..247 {
+            let is_device_at_address = self.get_control_function_by_address(Address(address));
+            let is_valid_device: bool = is_device_at_address.is_some();
+
+            if !is_valid_device {
+                return Address(address);
+            } else {
+                let device_at_our_address = is_device_at_address.as_ref().unwrap().borrow();
+
+                let preferred_address_name: u64 = match &*device_at_our_address {
+                    ControlFunction::External { name } => (*name).into(),
+                    ControlFunction::Internal { address_claim_data } => {
+                        address_claim_data.get_name().into()
+                    }
+                };
+
+                if <NAME as Into<u64>>::into(NAME::default()) == preferred_address_name {
+                    return Address(address);
+                }
+            }
+        }
+        Address::NULL
+    }
+
+    pub(super) fn construct_address_claim(source_address: Address, name: NAME) -> CANMessage {
+        let address_claim = <NAME as Into<u64>>::into(name).to_le_bytes().to_vec();
+
+        let request_id = CanId::try_encode(
+            Pgn::from_raw(CommonParameterGroupNumbers::AddressClaim as u32),
+            source_address,
+            Address::BROADCAST,
+            Priority::Default,
+        );
+        CANMessage::new(address_claim, request_id.unwrap())
+    }
+
+    pub(super) fn construct_request_for_address_claim() -> CANMessage {
+        let pgn_to_request: u32 = CommonParameterGroupNumbers::AddressClaim as u32;
+        let request = pgn_to_request.to_le_bytes().to_vec();
+        let request_id = CanId::try_encode(
+            Pgn::from_raw(CommonParameterGroupNumbers::ParameterGroupNumberRequest as u32),
+            Address::NULL,
+            Address::BROADCAST,
+            Priority::Three,
+        );
+        CANMessage::new(request, request_id.unwrap())
+    }
+
+    pub(super) fn enqueue_can_message(
+        &mut self,
+        message: CANMessage,
+        queue_priority: MessageQueuePriority,
+    ) {
+        // Todo, max queue depth?
+        match queue_priority {
+            MessageQueuePriority::High => {
+                self.high_priority_can_message_tx_queue.push_back(message)
+            }
+            MessageQueuePriority::Normal => {
+                self.normal_priority_can_message_tx_queue.push_back(message)
+            }
+        }
+    }
+
+    pub fn send_can_message(
+        &mut self,
+        parameter_group_number: Pgn,
+        data: &[u8],
+        source: Rc<RefCell<ControlFunction>>,
+        destination: Rc<RefCell<ControlFunction>>,
+        priority: Priority,
+    ) -> CANTransmitState {
+        if !data.is_empty() {
+            // Todo, handle lengths greater than 8
+
+            if data.len() <= 8 {
+                let source = source.borrow();
+                let destination = destination.borrow();
+                let message_id = CanId::try_encode(
+                    parameter_group_number,
+                    self.get_control_function_address_by_name(source.get_name()),
+                    self.get_control_function_address_by_name(destination.get_name()),
+                    priority,
+                )
+                .unwrap_or(CanId::default());
+
+                if message_id.raw() != CanId::default().raw() {
+                    self.enqueue_can_message(
+                        CANMessage::new(data.to_vec(), message_id),
+                        MessageQueuePriority::Normal,
+                    );
+                    return CANTransmitState::Success;
+                }
+            }
+        }
+        CANTransmitState::Fail
+    }
+
+    fn update_address_claiming(&mut self) {
+        let mut state_machines = std::mem::take(&mut self.address_claim_state_machines);
+        for address_claimer in &mut state_machines {
+            let mut address_claimer = address_claimer.borrow_mut();
+            match *address_claimer {
+                ControlFunction::Internal {
+                    ref mut address_claim_data,
+                } => {
+                    if address_claim_data.get_enabled() {
+                        match address_claim_data.get_state() {
+                            AddressClaimingState::None => {
+                                address_claim_data.set_state(
+                                    AddressClaimingState::update_state_none(address_claim_data),
+                                );
+                            }
+                            AddressClaimingState::WaitForClaim => {
+                                if address_claim_data.get_timestamp().is_none() {
+                                    address_claim_data.set_timestamp(Some(Instant::now()))
+                                }
+
+                                address_claim_data.set_state(
+                                    AddressClaimingState::update_state_wait_for_claim(
+                                        address_claim_data,
+                                    ),
+                                );
+                            }
+                            AddressClaimingState::SendRequestForClaim => {
+                                address_claim_data.set_state(
+                                    AddressClaimingState::update_state_send_request_for_claim(self),
+                                );
+                            }
+                            AddressClaimingState::WaitForRequestContentionPeriod => {
+                                address_claim_data.set_state(
+                                    AddressClaimingState::update_state_wait_for_request_contention(
+                                        address_claim_data,
+                                        self,
+                                    ),
+                                );
+                            }
+                            AddressClaimingState::SendPreferredAddressClaim
+                            | AddressClaimingState::SendReclaimAddressOnRequest
+                            | AddressClaimingState::ContendForPreferredAddress => {
+                                address_claim_data.set_state(
+                                    AddressClaimingState::update_state_send_preferred_address_claim(
+                                        address_claim_data,
+                                        self,
+                                    ),
+                                );
+                            }
+                            AddressClaimingState::SendArbitraryAddressClaim => {
+                                address_claim_data.set_state(
+                                    AddressClaimingState::update_state_send_arbitrary_address_claim(
+                                        address_claim_data,
+                                        self,
+                                    ),
+                                );
+                                address_claim_data
+                                    .set_preferred_address(self.get_next_free_arbitrary_address());
+                            }
+                            AddressClaimingState::AddressClaimingComplete
+                            | AddressClaimingState::UnableToClaim => {
+                                // Nothing to do
+                            }
+                        }
+                    }
+                }
+                _ => panic!("Only Internal CFs can perform address claiming"),
+            }
+        }
+        std::mem::swap(&mut state_machines, &mut self.address_claim_state_machines);
+    }
+
+    fn update_receive_messages(&mut self) {
+        while !self.receive_message_queue.is_empty() {
+            // Todo receive messages, need to generalize message handling
+            let current_message = self.receive_message_queue.front().unwrap();
+
+            // Process address claims and requests to claim
+            if NAME::default() == current_message.get_destination_name() {
+                // Broadcast Message
+                if current_message.get_identifier().pgn()
+                    == Pgn::from_raw(CommonParameterGroupNumbers::AddressClaim as u32)
+                {
+                    // Todo
+                } else if current_message.get_identifier().pgn()
+                    == Pgn::from_raw(
+                        CommonParameterGroupNumbers::ParameterGroupNumberRequest as u32,
+                    )
+                    && current_message.get_data().len() >= 3
+                {
+                    let message_data = current_message.get_data();
+                    let requested_pgn: u32 = (message_data[0] as u32)
+                        | ((message_data[1] as u32) << 8)
+                        | ((message_data[2] as u32) << 16);
+
+                    if requested_pgn
+                        == CommonParameterGroupNumbers::ParameterGroupNumberRequest as u32
+                    {
+                        for internal_cf in &mut self.address_claim_state_machines {
+                            let mut address_claimer = internal_cf.borrow_mut();
+                            match *address_claimer {
+                                ControlFunction::Internal {
+                                    ref mut address_claim_data,
+                                } => {
+                                    if address_claim_data.get_state()
+                                        == AddressClaimingState::AddressClaimingComplete
+                                    {
+                                        address_claim_data.set_state(
+                                            AddressClaimingState::SendReclaimAddressOnRequest,
+                                        );
+                                    }
+                                }
+                                ControlFunction::External { name: _ } => {}
+                            }
+                        }
+                    }
+                } else {
+                    // Destination specific
+                }
+
+                self.receive_message_queue.pop_front();
+            }
+        }
+    }
+
+    fn update_transmit_messages(&mut self) {
+        let should_continue_sending: bool = true; // Todo, check driver return values.
+
+        while !self.high_priority_can_message_tx_queue.is_empty() {
+            // todo hand off to driver
+            self.high_priority_can_message_tx_queue.pop_front();
+        }
+
+        while should_continue_sending && !self.normal_priority_can_message_tx_queue.is_empty() {
+            // todo hand off to driver
+            self.normal_priority_can_message_tx_queue.pop_front();
+        }
+    }
+
+    pub fn update(mut self) {
+        self.update_receive_messages();
+        self.update_address_claiming();
+        self.update_transmit_messages();
+    }
+}
+
+impl Default for NetworkManager {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_creating_network_manager() {
+        let network = NetworkManager::new();
+        network.update();
+    }
+
+    #[test]
+    fn test_creating_internal_control_function() {
+        let mut network = NetworkManager::new();
+        let test_name = NAME::builder()
+            .device_class(0)
+            .device_class_instance(0)
+            .ecu_instance(0)
+            .function_code(130)
+            .function_instance(0)
+            .identity_number(123_u32)
+            .industry_group(2)
+            .function_instance(0)
+            .build();
+
+        let new_cf = ControlFunction::new_internal_control_function(
+            test_name,
+            Address(0x81),
+            true,
+            &mut network,
+        );
+
+        assert_eq!(
+            <NAME as Into<u64>>::into(new_cf.borrow().get_name()),
+            test_name.into()
+        );
+    }
+}
+
\ 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/ayu-614652228113ac93.css b/static.files/ayu-614652228113ac93.css new file mode 100644 index 0000000..8fd09c9 --- /dev/null +++ b/static.files/ayu-614652228113ac93.css @@ -0,0 +1 @@ + :root{--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);--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;--source-sidebar-background-selected:#14191f;--source-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:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--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);}h1,h2,h3,h4,h1 a,.sidebar h2 a,.sidebar h3 a,#source-sidebar>.title{color:#fff;}h4{border:none;}.docblock code{color:#ffb454;}.docblock a>code{color:#39AFD7 !important;}.code-header,.docblock pre>code,pre,pre>code,.item-info code,.rustdoc.source .example-wrap{color:#e6e1cf;}.sidebar .current,.sidebar a:hover,#source-sidebar div.files>a:hover,details.dir-entry summary:hover,#source-sidebar div.files>a:focus,details.dir-entry summary:focus,#source-sidebar div.files>a.selected{color:#ffb44c;}.sidebar-elems .location{color:#ff7733;}.src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}.search-results a:hover,.search-results a:focus{color:#fff !important;background-color:#3c3c3c;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}#search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}#search-tabs>button:not(.selected){border:none;background-color:transparent !important;}#search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#settings-menu>a img{filter:invert(100);} \ No newline at end of file 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/dark-1097f8e92a01e3cf.css b/static.files/dark-1097f8e92a01e3cf.css new file mode 100644 index 0000000..1e5e7d1 --- /dev/null +++ b/static.files/dark-1097f8e92a01e3cf.css @@ -0,0 +1 @@ +: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);--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;--source-sidebar-background-selected:#333;--source-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:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--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/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/light-0f8c037637f9eb3e.css b/static.files/light-0f8c037637f9eb3e.css new file mode 100644 index 0000000..21c3a85 --- /dev/null +++ b/static.files/light-0f8c037637f9eb3e.css @@ -0,0 +1 @@ +: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);--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:#ffffff;--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:#4e8bca;--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;--source-sidebar-background-selected:#fff;--source-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);} \ No newline at end of file diff --git a/static.files/main-0795b7d26be81095.js b/static.files/main-0795b7d26be81095.js new file mode 100644 index 0000000..87b4338 --- /dev/null +++ b/static.files/main-0795b7d26be81095.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 mobileLocationTitle=document.querySelector(".mobile-topbar h2");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileLocationTitle&&locationTitle){mobileLocationTitle.innerHTML=locationTitle.innerHTML}}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 loadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="stylesheet";document.getElementsByTagName("head")[0].appendChild(link)}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();loadCss(getVar("static-root-path")+getVar("settings-css"));loadScript(getVar("static-root-path")+getVar("settings-js"));preLoadCss(getVar("static-root-path")+getVar("theme-light-css"));preLoadCss(getVar("static-root-path")+getVar("theme-dark-css"));preLoadCss(getVar("static-root-path")+getVar("theme-ayu-css"));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)}}}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 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=name+"/index.html"}else{path=shortty+"."+name+".html"}const current_page=document.location.href.split("/").pop();const link=document.createElement("a");link.href=path;if(path===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("union","unions","Unions");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Definitions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");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&&!/^(?:[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)}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=function(ev){if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=function(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=function(){this.TOOLTIP_FORCE_VISIBLE=this.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!this.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(this);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointermove=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!this.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=function(switchFocus){hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=function(){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-13285aec31fa243e.css b/static.files/noscript-13285aec31fa243e.css new file mode 100644 index 0000000..c32e0cb --- /dev/null +++ b/static.files/noscript-13285aec31fa243e.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.source .sidebar{display:none;}.notable-traits{display:none;} \ 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-9bb858ba049f1f21.css b/static.files/rustdoc-9bb858ba049f1f21.css new file mode 100644 index 0000000..73eacd8 --- /dev/null +++ b/static.files/rustdoc-9bb858ba049f1f21.css @@ -0,0 +1,8 @@ + :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.srclink,#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,#source-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{margin:0 0 .75em 0;}p: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;}.source 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;}.source .content pre{padding:20px;}.rustdoc.source .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.source .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,#source-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.source .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.source-sidebar-expanded .source .sidebar{overflow-y:auto;flex-basis:300px;}.source-sidebar-expanded .source .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;}.sidebar .logo-container{margin-top:10px;margin-bottom:10px;text-align:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}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>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.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;}.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(.source) .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.source .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;}.source 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);}@-moz-document url-prefix(){#crate-search{padding-left:0px;padding-right:19px;}}#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 span.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;}.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;}#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;}.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.source .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;}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;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;}#source-sidebar{width:100%;overflow:auto;}#source-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#source-sidebar div.files>a:hover,details.dir-entry summary:hover,#source-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--source-sidebar-background-hover);}#source-sidebar div.files>a.selected{background-color:var(--source-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: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;}.source main,.rustdoc.source .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.source-sidebar-expanded .source .sidebar,.rustdoc:not(.source) .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;}#search-tabs .count{display:block;}#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;}.source-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;}.source-sidebar-expanded .source .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;}.source 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.srclink,#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;} \ 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-f6292fe389d70017.js b/static.files/search-f6292fe389d70017.js new file mode 100644 index 0000000..c91355a --- /dev/null +++ b/static.files/search-f6292fe389d70017.js @@ -0,0 +1,5 @@ +"use strict";(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",];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 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-1}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:-1,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:-1,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,literalSearch:false,error:null,correction: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;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){return unifyFunctionTypes(fnType.generics,queryElem.generics)}function unifyFunctionTypes(fnTypes,queryElems){if(queryElems.length===0){return true}if(!fnTypes||fnTypes.length===0){return false}const queryElemSet=new Map();const addQueryElemToQueryElemSet=function addQueryElemToQueryElemSet(queryElem){let currentQueryElemList;if(queryElemSet.has(queryElem.id)){currentQueryElemList=queryElemSet.get(queryElem.id)}else{currentQueryElemList=[];queryElemSet.set(queryElem.id,currentQueryElemList)}currentQueryElemList.push(queryElem)};for(const queryElem of queryElems){addQueryElemToQueryElemSet(queryElem)}const fnTypeSet=new Map();const addFnTypeToFnTypeSet=function addFnTypeToFnTypeSet(fnType){const queryContainsArrayOrSliceElem=queryElemSet.has(typeNameIdOfArrayOrSlice);if(fnType.id===-1||!(queryElemSet.has(fnType.id)||(fnType.id===typeNameIdOfSlice&&queryContainsArrayOrSliceElem)||(fnType.id===typeNameIdOfArray&&queryContainsArrayOrSliceElem))){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentQueryElemList=queryElemSet.get(fnType.id)||[];let matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)});if(matchIdx===-1&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)&&queryContainsArrayOrSliceElem){currentQueryElemList=queryElemSet.get(typeNameIdOfArrayOrSlice)||[];matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)})}if(matchIdx===-1){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentFnTypeList;if(fnTypeSet.has(fnType.id)){currentFnTypeList=fnTypeSet.get(fnType.id)}else{currentFnTypeList=[];fnTypeSet.set(fnType.id,currentFnTypeList)}currentFnTypeList.push(fnType)};for(const fnType of fnTypes){addFnTypeToFnTypeSet(fnType)}const doHandleQueryElemList=(currentFnTypeList,queryElemList)=>{if(queryElemList.length===0){return true}const queryElem=queryElemList.pop();const l=currentFnTypeList.length;for(let i=0;i{if(!fnTypeSet.has(id)){if(id===typeNameIdOfArrayOrSlice){return handleQueryElemList(typeNameIdOfSlice,queryElemList)||handleQueryElemList(typeNameIdOfArray,queryElemList)}return false}const currentFnTypeList=fnTypeSet.get(id);if(currentFnTypeList.length0?checkIfInList(row.generics,elem):false}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)}return true}return checkIfInList(row.generics,elem)}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,}}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);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);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)){return}if(!unifyFunctionTypes(row.type.output,parsedQuery.returned)){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);function convertNameToId(elem){if(typeNameIdMap.has(elem.name)){elem.id=typeNameIdMap.get(elem.name)}else if(!parsedQuery.literalSearch){let match=-1;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.name,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==-1){parsedQuery.correction=matchName}elem.id=match}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+"::"}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";if(item.is_alias){const alias=document.createElement("span");alias.className="alias";const bold=document.createElement("b");bold.innerText=item.alias;alias.appendChild(bold);alias.insertAdjacentHTML("beforeend"," - see ");resultName.appendChild(alias)}resultName.insertAdjacentHTML("beforeend",`\ +${typeName}\ +
\ + ${item.displayPath}${name}\ +
`);link.appendChild(resultName);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){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.

`}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){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;return types.map(type=>{let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}return{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics: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"){const pathIndex=functionSearchType[INPUTS_DATA];inputs=[{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){const pathIndex=functionSearchType[OUTPUT_DATA];output=[{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}return{inputs,output,}}function buildIndex(rawSearchIndex){searchIndex=[];const searchWords=[];typeNameIdMap=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;typeNameIdOfArray=buildTypeMapIndex("array");typeNameIdOfSlice=buildTypeMapIndex("slice");typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");for(const crate in rawSearchIndex){if(!hasOwnPropertyRustdoc(rawSearchIndex,crate)){continue}let crateSize=0;const crateCorpus=rawSearchIndex[crate];searchWords.push(crate);const crateRow={crate:crate,ty:1,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),deprecated:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionSearchTypes=crateCorpus.f;const deprecatedItems=new Set(crateCorpus.c);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.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),};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-8c76f75bfb6bd192.css b/static.files/settings-8c76f75bfb6bd192.css new file mode 100644 index 0000000..5241bb8 --- /dev/null +++ b/static.files/settings-8c76f75bfb6bd192.css @@ -0,0 +1,3 @@ +.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;} \ No newline at end of file diff --git a/static.files/settings-de11bff964e9d4e5.js b/static.files/settings-de11bff964e9d4e5.js new file mode 100644 index 0000000..cc508a8 --- /dev/null +++ b/static.files/settings-de11bff964e9d4e5.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=function(){changeSetting(this.id,this.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=function(event){event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=function(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/source-script-106908c7a7964ba4.js b/static.files/source-script-106908c7a7964ba4.js new file mode 100644 index 0000000..191bf6d --- /dev/null +++ b/static.files/source-script-106908c7a7964ba4.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,"source-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"source-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 createSourceSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="source-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(sourcesIndex).forEach(key=>{sourcesIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(sourcesIndex[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 highlightSourceLines(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 handleSourceHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSourceLines()}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 highlightSourceLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSourceHighlight)});highlightSourceLines();window.createSourceSidebar=createSourceSidebar})() \ No newline at end of file diff --git a/static.files/storage-59fd9b8ccb335783.js b/static.files/storage-59fd9b8ccb335783.js new file mode 100644 index 0000000..ca5481a --- /dev/null +++ b/static.files/storage-59fd9b8ccb335783.js @@ -0,0 +1 @@ +"use strict";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)}let newHref;if(newThemeName==="light"||newThemeName==="dark"||newThemeName==="ayu"){newHref=getVar("static-root-path")+getVar("theme-"+newThemeName+"-css")}else{newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css"}if(!window.currentTheme){document.write(``);window.currentTheme=document.getElementById("themeStyle")}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,"source-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