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
impl GffDocument
Sourcepub fn open(source: &[u8]) -> Result<Self, GffBinaryError>
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.
Sourcepub fn revision(&self) -> u64
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.
Sourcepub fn is_edited(&self) -> bool
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.
Sourcepub fn changes(&self) -> &BTreeMap<GffPath, Change>
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.
Sourcepub fn view<T: FromGff>(&self) -> Result<T, T::Error>
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.
Sourcepub fn get(&self, path: &str) -> Result<&GffValue, GffDocumentError>
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.
Sourcepub fn get_at(&self, at: &GffPath) -> Result<&GffValue, GffPathError>
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.
Sourcepub fn struct_id_at(&self, at: &GffPath) -> Result<i32, GffPathError>
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.
Sourcepub fn get_as<T: GffScalar>(&self, path: &str) -> Result<T, GffDocumentError>
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.
Sourcepub fn set(
&mut self,
path: &str,
value: impl GffScalar,
) -> Result<GffValue, GffDocumentError>
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.
Sourcepub fn insert(
&mut self,
path: &str,
value: impl GffScalar,
) -> Result<(), GffDocumentError>
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.
Sourcepub fn remove(&mut self, path: &str) -> Result<GffValue, GffDocumentError>
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.
Sourcepub fn set_at(
&mut self,
at: &GffPath,
value: GffValue,
) -> Result<GffValue, GffPathError>
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.
Sourcepub fn insert_at(
&mut self,
at: &GffPath,
value: GffValue,
) -> Result<(), GffPathError>
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.
Sourcepub fn remove_at(&mut self, at: &GffPath) -> Result<GffValue, GffPathError>
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.
Sourcepub fn push_element(
&mut self,
path: &str,
element: GffStruct,
) -> Result<usize, GffDocumentError>
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.
Sourcepub fn push_element_at(
&mut self,
at: &GffPath,
element: GffStruct,
) -> Result<usize, GffPathError>
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.
Sourcepub fn set_struct_id_at(
&mut self,
at: &GffPath,
struct_id: i32,
) -> Result<i32, GffPathError>
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.
Sourcepub fn records_at(path: &GffPath) -> GffPath
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.
Sourcepub fn save(&self) -> Result<Vec<u8>, GffBinaryError>
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
impl Clone for GffDocument
Source§fn clone(&self) -> GffDocument
fn clone(&self) -> GffDocument
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for GffDocument
impl Debug for GffDocument
Source§impl PartialEq for GffDocument
impl PartialEq for GffDocument
Source§fn eq(&self, other: &GffDocument) -> bool
fn eq(&self, other: &GffDocument) -> bool
self and other values to be equal, and is used by ==.