Skip to main content

GffStruct

Struct GffStruct 

Source
pub struct GffStruct {
    pub struct_id: i32,
    pub fields: Vec<GffField>,
}
Expand description

One GFF struct node.

Fields§

§struct_id: i32

Struct ID from the binary table.

§fields: Vec<GffField>

Ordered fields for this struct.

Implementations§

Source§

impl GffStruct

Source

pub fn get(&self, path: &GffPath) -> Result<&GffValue, GffPathError>

Reads the value a path names.

The read counterpart to Self::set, and the way to do a read-modify-write over a large file without building a typed view per field.

§Errors

Every operation here walks the path the same way and can fail the same way partway along it: GffPathError::EmptyPath for a path with no segments, GffPathError::IndexAtRoot for one starting with an index, GffPathError::NotAStruct or GffPathError::NotAList when a segment’s value is not the kind the next segment needs, GffPathError::IndexOutOfRange when a list is shorter than the index, GffPathError::NoSuchField when a struct does not carry the label, and GffPathError::AmbiguousLabel when it carries it more than once. That last one is a refusal rather than a first match; see the module docs.

On top of those, GffPathError::WrongSegmentKind when path ends in an index. That lands on a bare GffStruct, which is not a GffValue; Self::struct_id is the call that takes such a path.

Source

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

Replaces the value a path names, returning what was there.

Refuses a label the struct does not already carry, and refuses a replacement of a different type from the one stored. Both refusals exist because the alternative is a file that looks edited and is not: an appended duplicate loses to the original on lookup, and a widened integer shifts every byte after it.

To change a field’s type on purpose, remove it and insert it back.

§Errors

The walk failures Self::get lists, plus GffPathError::TypeMismatch when value is not the type the field already holds. GffPathError::NoSuchField is the ordinary way a mistyped label arrives here rather than becoming a new field.

Source

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

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

The value’s own type decides the field’s type, there being nothing to preserve.

On disk a struct holding one field stores that field’s index directly and a struct holding more stores an offset into the shared index array, so adding a second field to a one-field struct changes the struct’s encoded shape. Nothing here has to arrange that: the writer picks the shape from the field count when it encodes.

§Errors

The walk failures Self::get lists for the path’s parent, plus GffPathError::AlreadyExists when the struct already carries that label. Adding a second copy is refused rather than done, because the original would go on winning every lookup.

Source

pub fn insert_at_position( &mut self, path: &GffPath, value: GffValue, position: usize, ) -> Result<(), GffPathError>

Adds a field among its siblings rather than after them.

position is clamped to the end, so usize::MAX appends and a position from a struct that has since lost fields still lands somewhere valid.

This exists because putting a field back is not the same operation as adding one. A GFF struct stores its fields in order and the writer emits them in that order, so restoring a removed field by appending produces a file that differs from the original everywhere after the hole, which is what an undo of a deletion did before.

§Errors

The same as Self::insert. position is clamped rather than checked, so it is never the reason this fails.

Source

pub fn position(&self, path: &GffPath) -> Option<usize>

Where the field path names sits among its siblings.

None when the parent does not resolve, the path does not end in a label, or no such field is there.

Source

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

Removes what a path names, returning it.

A path ending in a label removes that field. A path ending in an index removes that list element and returns it wrapped in a GffValue::Struct.

Removing an element does not renumber its siblings. No list in the engine reads an element’s struct id as a position, so the ids that remain still mean what they meant.

§Errors

The walk failures Self::get lists. Nothing is removed when any of them fires, so a failed remove leaves the tree as it was.

Source

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

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

The element carries its own struct_id, and choosing it is the caller’s job. Several lists have the engine compare that id against a per-list constant and silently skip an element that does not match, and which constant belongs to which list is per-format knowledge that lives above this crate.

§Errors

The walk failures Self::get lists, with GffPathError::NotAList the one that means path named a field that is not a list. The element’s struct_id is not checked against anything, since nothing here knows which list wants which id.

Source

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

Reads the struct id of the list element a path names.

An element’s id is not a field and not a GffValue, so get cannot reach it: a path ending in an index lands on a bare GffStruct. A nested struct field needs nothing special, since get hands back the GffValue::Struct and the id is on the struct inside it.

Some formats carry meaning there. A UTC’s equipment slot is its Equip_ItemList element’s struct id and appears in no field, so reading which slot an item occupies is exactly this call.

§Errors

The walk failures Self::get lists, plus GffPathError::WrongSegmentKind when path ends in a label rather than an index. That is the mirror of get’s refusal: this call takes exactly the paths that one will not.

Source

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

Sets the struct id of the list element a path names, returning the old.

The counterpart to struct_id, and the way to move a UTC equipment item between slots: the slot is the id, so re-equipping is a change to an existing element rather than a removal and an append.

Which ids a list accepts is the caller’s to know. Several lists have the engine compare the id against a per-list constant and silently skip an element that does not match, and that mapping is per-format knowledge living above this crate.

§Errors

The same as Self::struct_id. struct_id itself is not validated, so an id no list accepts is written without complaint.

Source§

impl GffStruct

Source

pub fn walk(&self) -> GffWalk<'_>

Every value beneath this struct, with the address it sits at.

Depth first in the order the file holds its fields, so a consumer printing the sequence gets the tree as it is laid out rather than sorted into something else. A struct-typed field is yielded before what is inside it, and a list before its elements.

§What the paths are good for

Every one of them ends at a field, so every one is a path get accepts. That is not incidental: a path ending at a list element names a struct rather than a value, which get refuses, so the walk never produces one. The addresses are the same ones a document’s change map and a lint finding use.

§Where a path does not resolve

A struct may carry one label more than once, and vanilla content does: each EntryList and ReplyList node of some dialogues carries SoundExists six times. Every copy is yielded, since dropping one would make the walk lie about what the file holds, and their paths are identical and name no single field. get refuses such an address, deliberately, so those paths come back AmbiguousLabel rather than resolving to a guess.

The alternative was an occurrence number inside the address itself. That was not taken because the address type is shared with the linter, the change map and the diff, and this is not a shared problem: across every GFF in an install it happens for one label, in two lists, in one resource type. Across every save reachable from here, including the per-module resources inside their nested archives, it does not happen at all. A consumer that reads dialogue needs to expect it; a save editor never meets it.

Source§

impl GffStruct

Source

pub fn new(struct_id: i32) -> Self

Creates an empty struct with the given struct_id.

Source

pub fn with_fields(struct_id: i32, fields: Vec<GffField>) -> Self

Creates a struct with pre-populated fields.

Source

pub fn push_field(&mut self, label: GffLabel, value: GffValue)

Appends a new field.

Takes a built GffLabel rather than converting one, so the decision about an unrepresentable label belongs to whoever supplied it. A source literal goes through gff_label! and fails the build; a label read out of a file or a user’s input goes through GffLabel::new and carries a Result the caller has to answer.

Source

pub fn field(&self, label: &str) -> Option<&GffValue>

Returns the first field value that matches label, or None when the struct carries no field under that label.

A struct can hold one label more than once, and vanilla content does: every EntryList and ReplyList node in a .dlg carries SoundExists six times over. Across every GFF file in the install the copies agree in value, so taking the first is not a choice between different answers. It is still a choice, and a caller that wants to see the rest has to walk Self::fields itself.

Trait Implementations§

Source§

impl Clone for GffStruct

Source§

fn clone(&self) -> GffStruct

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 GffStruct

Source§

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

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

impl PartialEq for GffStruct

Source§

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

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.