Skip to main content

GffDocument

Struct GffDocument 

Source
pub struct GffDocument { /* private fields */ }
Expand description

One open GFF file: its bytes, its tree, and what has happened to it.

Implementations§

Source§

impl GffDocument

Source

pub fn open(source: &[u8]) -> Result<Self, GffBinaryError>

Parses source and keeps a copy of it.

§Errors

Returns GffBinaryError when the bytes are not a GFF this reader accepts.

Source

pub fn revision(&self) -> u64

How many times this document has been mutated.

Zero on open, rising by one per mutation that the tree accepted. A mutation returning a value to what the file held records no change and still counts, so this moves when changes does not.

For a consumer caching state derived from the tree.

Source

pub fn gff(&self) -> &Gff

The parsed tree, including everything no view models.

Source

pub fn is_edited(&self) -> bool

Whether the tree differs from the file this was opened from.

Whether the content differs, not whether a mutator ran. Setting a field to the value it already held leaves this false, which matters because a UI binding a text field writes the unchanged value on every redraw and save re-serialises whenever this is true.

Source

pub fn changes(&self) -> &BTreeMap<GffPath, Change>

Every address whose content differs from the opened file, in path order.

Recorded as the edits are made rather than derived by comparing trees. This document is the only thing that can change its own tree, so a map it keeps cannot fall behind: gff lends the tree for reading, view hands back an owned projection, and the four mutators all funnel through one recording point. The drift that makes an event log untrustworthy is a hazard for something observing mutations, not for the one making them.

An address that has come back to what it held is not in here. Setting a field and setting it back leaves nothing, appending an element and removing it again leaves nothing, and setting one field twice leaves one entry against the value the file was opened with.

Source

pub fn view<T: FromGff>(&self) -> Result<T, T::Error>

Reads this file as a typed view.

The view is a projection and reading one changes nothing here, so a caller can take several views of the same document and still save the file it opened.

§Errors

Whatever the view’s own reader reports.

Source

pub fn get(&self, path: &str) -> Result<&GffValue, GffDocumentError>

Reads the value at path, in the dot notation ClassList[0].Class.

Parses the text and delegates to get_at. A caller that already holds a GffPath wants that one instead: this renders nothing and allocates nothing, but it does have to parse, and a caller looping over addresses it already has would be paying for a round trip through text it never needed.

§Errors

GffDocumentError::Syntax when the text is not an address, and GffDocumentError::Path when it does not name exactly one field of this tree.

Source

pub fn get_at(&self, at: &GffPath) -> Result<&GffValue, GffPathError>

Reads the value at names.

§Errors

GffPathError when the address does not name exactly one field of this tree. There is no syntax error to report, which is the whole difference between this family and the text one.

Source

pub fn struct_id_at(&self, at: &GffPath) -> Result<i32, GffPathError>

The struct id of the list element at names.

The reader half of set_struct_id_at, and the only way to see an id without reaching past this document into the tree. Several formats put meaning there and in no field: a UTC’s equipment slot is its Equip_ItemList element’s id, so reading which slot an item occupies is exactly this call.

§Errors

GffPathError when at does not end in a list index, or indexes past the end of the list.

Source

pub fn get_as<T: GffScalar>(&self, path: &str) -> Result<T, GffDocumentError>

Reads the value at path as T.

The typed counterpart to get, which hands back the wire value and leaves the caller to match on its variant. Every field a panel binds a control to goes through that unwrap, so it is written here once instead of at each of them.

Accepts every encoding the type can be read from, which is GffScalar’s own tolerance rather than a second rule: a field declared narrower than the caller’s type still reads.

§Errors

GffDocumentError::Syntax when the text is not an address, GffDocumentError::Path when it names no single field, and GffDocumentError::WrongType when the field is there and holds something else. The last is kept apart from the second because a field that is absent and a field that is the wrong shape are different facts about the file.

Source

pub fn set( &mut self, path: &str, value: impl GffScalar, ) -> Result<GffValue, GffDocumentError>

Replaces the value at path, returning what was there.

The field has to be present already and the replacement has to be the width the field stores. Both refusals are GffStruct::set’s, and its docs say why.

§Errors

GffDocumentError::Syntax when the text is not an address, and GffDocumentError::Path when the field is absent, is carried more than once, or stores a different width.

Source

pub fn insert( &mut self, path: &str, value: impl GffScalar, ) -> Result<(), GffDocumentError>

Adds the field path names, which must not already be there.

The value’s own type decides the field’s type: there is nothing stored to preserve, which is why this takes what it is given where set refuses a width change.

Scalars only, and that is this spelling’s limit rather than the document’s: insert_at takes a GffValue, so a caller adding a list or a nested struct goes through that one. A raw tree offering “add a field” does exactly that.

§Errors

GffDocumentError::Syntax when the text is not an address, and GffDocumentError::Path when the parent does not resolve or the label is already there.

Source

pub fn remove(&mut self, path: &str) -> Result<GffValue, GffDocumentError>

Removes what path names, returning it.

A path ending in a label removes that field; one ending in an index removes that list element and hands it back wrapped in a GffValue::Struct. Siblings are not renumbered, for the reason GffStruct::remove gives.

§Errors

GffDocumentError::Syntax when the text is not an address, and GffDocumentError::Path when it names nothing, names a field carried more than once, or indexes past the end of a list.

Source

pub fn set_at( &mut self, at: &GffPath, value: GffValue, ) -> Result<GffValue, GffPathError>

Replaces the value at at, taking the address and the value as they stand.

The typed counterpart to set, for a caller that already holds both. Reverting a change-review row is the case this exists for: changes is keyed by GffPath and hands back a GffValue, so rendering that address back to text and picking a Rust type to put the value through would be undoing work twice.

§Errors

GffPathError when the field is absent, is carried more than once, or stores a different width.

Source

pub fn insert_at( &mut self, at: &GffPath, value: GffValue, ) -> Result<(), GffPathError>

Adds the field at names, taking the value as it stands.

The typed counterpart to insert, and the other half of reverting a row: a change whose before was None reverts by removing, and one whose current is None reverts by inserting what was there.

§Errors

GffPathError when the parent does not resolve or the label is already there.

A field the opened file carried goes back where the file had it. A struct stores its fields in order and the writer emits them in that order, so putting one back on the end would rewrite the file from the hole onwards. A field the file never had is appended, there being no position to restore.

Source

pub fn remove_at(&mut self, at: &GffPath) -> Result<GffValue, GffPathError>

Removes what at names, returning it.

The typed counterpart to remove.

§Errors

GffPathError when it names nothing, names a field carried more than once, or indexes past the end of a list.

Source

pub fn push_element( &mut self, path: &str, element: GffStruct, ) -> Result<usize, GffDocumentError>

Appends element to the list path names, returning its index.

The element carries its own struct id and choosing it is the caller’s, because several lists have the engine skip an element whose id is wrong and which id belongs to which list is per-format knowledge this layer does not hold.

§Errors

GffDocumentError::Syntax when the text is not an address, and GffDocumentError::Path when it does not name a list of this tree.

Source

pub fn push_element_at( &mut self, at: &GffPath, element: GffStruct, ) -> Result<usize, GffPathError>

Appends element to the list at names, returning its index.

The typed counterpart to push_element. Choosing the element’s struct id stays the caller’s, for the reason given there.

§Errors

GffPathError when at does not name a list of this tree.

Source

pub fn set_struct_id_at( &mut self, at: &GffPath, struct_id: i32, ) -> Result<i32, GffPathError>

Sets the struct id of the list element at names, returning the old one.

Some formats carry meaning in an element’s id rather than in any field. A UTC’s equipment slot is its Equip_ItemList element’s struct id, so moving an item between slots is this call rather than a removal and an append. Which ids a list accepts stays the caller’s to know, for the reason it is on push_element.

§The change lands on the list, not on the element

Not a choice about where it reads best. A Change holds a GffValue, a list holds its elements as GffStruct, and no value in the tree stands for one element. That is the same shortfall get refuses an index-terminated address over. The list is the shallowest node that has a value, and an element’s id is inside it, so the comparison already sees an id change with nothing new to observe it with.

Nothing inside the element moves, so a change recorded under it stays recorded.

§Errors

GffPathError when at does not end in a list index, or indexes past the end of the list.

Source

pub fn records_at(path: &GffPath) -> GffPath

The address a mutation on path is recorded against.

The path itself, except for a list element: removing ItemList[1] shifts every sibling after it, so ItemList[1] now holds what ItemList[2] did and recording against it would describe a change nobody made. The list is the shallowest node whose content actually differs, so that is where it lands.

Public because a caller building an undo stack has to read the same value either side of a mutation, and it can only do that if it knows where the mutation will land. Working it out a second time from the same rule is how the two come to disagree about a list element.

Source

pub fn save(&self) -> Result<Vec<u8>, GffBinaryError>

The file to write back.

The bytes this document was opened with, byte for byte, until an edit has landed. After one, the tree re-serialised.

§Errors

Returns GffBinaryError when the edited tree cannot be encoded, which a tree read out of a file and edited through these mutators cannot reach: everything they store is a value this crate can encode.

Trait Implementations§

Source§

impl Clone for GffDocument

Source§

fn clone(&self) -> GffDocument

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for GffDocument

Source§

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

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

impl PartialEq for GffDocument

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for GffDocument

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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 T
where 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> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

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 T
where U: Into<T>,

Source§

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 T
where U: TryFrom<T>,

Source§

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

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.