### pub fn requirements(&self) -> &[File] Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Gets the files that the plugin requires to be installed. ```APIDOC ## pub fn requirements(&self) -> &[File] ### Description Gets the files that the plugin requires to be installed. ### Method requirements ### Return Value &[File] - A slice of required files. ``` -------------------------------- ### Load all installed plugins helper for sort_plugins tests Source: https://docs.rs/libloot/latest/src/libloot/game.rs.html Helper function that loads all installed plugins by reading the initial load order, converting names to Path, and calling load_current_load_order_state and load_plugins. Used by sort_plugins tests. ```rust use crate::tests::initial_load_order; use super::*; fn load_all_installed_plugins(game: &mut Game, fixture: &Fixture) { let load_order = initial_load_order(fixture.game_type); let plugins: Vec<_> = load_order.iter().map(|(n, _)| Path::new(n)).collect(); game.load_current_load_order_state().unwrap(); game.load_plugins(&plugins).unwrap(); } ``` -------------------------------- ### Test setup for non-plugin file Source: https://docs.rs/libloot/latest/src/libloot/game.rs.html Sets up a game fixture for a parameterized test over all game types. Creates a Game with local path and unwraps the result. ```rust let fixture = Fixture::new(game_type); let game = Game::with_local_path( fixture.game_type, &fixture.game_path, &fixture.local_path, ) .unwrap(); ``` -------------------------------- ### pub fn set_requirements(&mut self, files: Vec) Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Sets the files that the plugin requires to be installed. ```APIDOC ## pub fn set_requirements(&mut self, files: Vec) ### Description Sets the files that the plugin requires to be installed. ### Method set_requirements ### Parameters - **files** (Vec) - Required - The required files. ``` -------------------------------- ### pub fn load_after_files(&self) -> &[File] Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Gets the plugins that the plugin must load after, returned as a slice of File objects. ```APIDOC ## pub fn load_after_files(&self) -> &[File] ### Description Gets the plugins that the plugin must load after. ### Method load_after_files ### Return Value &[File] - A slice of File objects. ``` -------------------------------- ### pub fn incompatibilities(&self) -> &[File] Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Gets the files that the plugin is incompatible with. ```APIDOC ## pub fn incompatibilities(&self) -> &[File] ### Description Gets the files that the plugin is incompatible with. ### Method incompatibilities ### Return Value &[File] - A slice of incompatible files. ``` -------------------------------- ### Database tests with fixture setup Source: https://docs.rs/libloot/latest/src/libloot/database/mod.rs.html Test module for database operations. It sets up a fixture with prelude and metadata YAML files, then tests loading masterlists, preludes, and userlists, asserting known bash tags. ```rust #[cfg(test)] mod tests { use std::path::PathBuf; use crate::{ EdgeType, GameType, metadata::{File, MessageType}, tests::{BLANK_DIFFERENT_ESM, BLANK_ESM, BLANK_MASTER_DEPENDENT_ESM}, }; use super::*; struct Fixture { inner: crate::tests::Fixture, prelude_path: PathBuf, metadata_path: PathBuf, } impl Fixture { fn new(game_type: GameType) -> Self { let inner = crate::tests::Fixture::new(game_type); let prelude = "- &preludeBashTag Actors.ACBS"; let prelude_path = inner.local_path.join("prelude.yaml"); std::fs::write(&prelude_path, prelude).unwrap(); let metadata = " prelude: - &preludeBashTag C.Climate bash_tags: - *preludeBashTag globals: - type: say content: 'A general message' condition: 'file(\"missing.esp\")' groups: - name: group1 - name: group2 after: - group1 plugins: - name: Blank.esm after: - Oblivion.esm msg: - type: say content: 'A note message' condition: 'file(\"missing.esp\")' tag: - Actors.ACBS - Actors.AIData - '-C.Water' - name: Blank - Different.esm after: - Blank - Master Dependent.esm msg: - type: warn content: 'A warning message' dirty: - crc: 0x7d22f9df util: TES4Edit udr: 4 - name: Blank - Different.esp after: - Blank - Plugin Dependent.esp msg: - type: error content: 'An error message' - name: Blank.esp after: - Blank - Different Master Dependent.esp - name: Blank - Different Master Dependent.esp after: - Blank - Master Dependent.esp msg: - type: say content: 'A note message' - type: warn content: 'A warning message' - type: error content: 'An error message'"; let metadata_path = inner.local_path.join("metadata.yaml"); std::fs::write(&metadata_path, metadata).unwrap(); Self { inner, prelude_path, metadata_path, } } fn database(&self) -> Database { Database::new(loot_condition_interpreter::State::new( self.inner.game_type.into(), self.inner.data_path(), )) } } fn truncate_options() -> MetadataWriteOptions { let mut options = MetadataWriteOptions::new(); options.set_truncate(true); options } #[test] fn load_masterlist_should_succeed_if_given_a_valid_path() { let fixture = Fixture::new(GameType::Oblivion); let mut database = fixture.database(); database.load_masterlist(&fixture.metadata_path).unwrap(); assert_eq!( &["C.Climate"], database .known_bash_tags(MergeMode::WithUserMetadata) .as_slice() ); } #[test] fn load_masterlist_with_prelude_should_succeed_if_given_valid_paths() { let fixture = Fixture::new(GameType::Oblivion); let mut database = fixture.database(); database .load_masterlist_with_prelude(&fixture.metadata_path, &fixture.prelude_path) .unwrap(); assert_eq!( &["Actors.ACBS"], database .known_bash_tags(MergeMode::WithUserMetadata) .as_slice() ); } #[test] fn load_userlist_should_succeed_if_given_a_valid_path() { let fixture = Fixture::new(GameType::Oblivion); let mut database = fixture.database(); database.load_userlist(&fixture.metadata_path).unwrap(); assert_eq!( &["C.Climate"], database ); } } ``` -------------------------------- ### Build groups graph with BU groups and start PluginsGraph Source: https://docs.rs/libloot/latest/src/libloot/sorting/plugins.rs.html Builds a groups graph with two sets of groups (including a default group and BU1/BU2 groups) and starts constructing a PluginsGraph with plugins A, B, and B1. The snippet is truncated at the point where the graph is being populated; the test name indicates it verifies that nodes are marked unfinishable if a node in their subtree is unfinishable. ```rust let fixture = Fixture::with_plugins(&[ PLUGIN_A, PLUGIN_B, PLUGIN_B1, PLUGIN_B2, PLUGIN_C, PLUGIN_D, ]); let groups_graph = build_groups_graph( &[ Group::new("A".into()), Group::new("B".into()).with_after_groups(vec!["A".into()]), Group::new("C".into()).with_after_groups(vec!["B".into()]), Group::new("D".into()).with_after_groups(vec!["C".into()]), Group::default(), ], &[ Group::new("BU1".into()).with_after_groups(vec!["B".into()]), Group::new("BU2".into()).with_after_groups(vec!["BU1".into()]), Group::new("C".into()).with_after_groups(vec!["BU2".into()]), ], ) .unwrap(); let mut graph = PluginsGraph::::new(); let a = graph.add_node(fixture.group_sorting_data(PLUGIN_A, "A")); let b = graph.add_node(fixture.group_sorting_data(PLUGIN_B, "B")); let b1 = graph.add_node(fixture.group_sorting_data(PLUGIN_B1, "BU1")); ``` -------------------------------- ### Test module with Fixture struct and with_plugins method Source: https://docs.rs/libloot/latest/src/libloot/sorting/plugins.rs.html Test setup for groups graph sorting, defining constants PLUGIN_A and PLUGIN_B, and a Fixture struct with a with_plugins constructor that builds a masterlist of groups. ```rust #[cfg(test)] mod tests { #![allow(clippy::many_single_char_names)] use super::*; use crate::sorting::{groups::build_groups_graph, test::TestPlugin}; const PLUGIN_A: &str = "A.esp"; const PLUGIN_B: &str = "B.esp"; struct Fixture { groups_graph: GroupsGraph, plugins: HashMap, } impl Fixture { fn with_plugins(plugin_names: &[&str]) -> Self { let masterlist = &[ Group::new("A".into()), Group::new("B".into()).with_after_groups(vec!["A".into()]), Group::new("C".into()), Group::new("default".into()).with_after_groups(vec!["C".into()]), Group::new("E".into()).with_after_groups(vec!["default".into()]), Group::new("F".into()).with_after_groups(vec!["E".into()]), ]; ``` -------------------------------- ### Test module imports and helper functions Source: https://docs.rs/libloot/latest/src/libloot/plugin/mod.rs.html Test module setup with imports and helper functions for selecting blank ESM files based on game type. ```rust #[cfg(test)] mod tests { use super::*; use crate::tests::ALL_GAME_TYPES; use array_parameterized_test::parameterized_test; mod plugin { use std::io::Seek; use std::io::Write; use tempfile::tempdir; use crate::tests::{ BLANK_ESL, BLANK_ESM, BLANK_ESP, BLANK_FULL_ESM, BLANK_MASTER_DEPENDENT_ESM, BLANK_MASTER_DEPENDENT_ESP, BLANK_MEDIUM_ESM, BLANK_OVERRIDE_ESP, NON_ASCII_ESM, source_plugins_path, }; use super::*; fn blank_esm(game_type: GameType) -> &'static str { if game_type == GameType::Starfield { BLANK_FULL_ESM } else { BLANK_ESM } } fn blank_master_dependent_esm(game_type: GameType) -> &'static str { if game_type == GameType::Starfield { "Blank - Override.full.esm" } else { BLANK_MASTER_DEPENDENT_ESM } } ``` -------------------------------- ### name Source: https://docs.rs/libloot/latest/libloot/struct.Plugin.html Get the plugin's filename. If the plugin was ghosted when it was loaded, this filename will be without the .ghost suffix, unless the game is OpenMW, in which case ghosted plugins are not supported. ```APIDOC ## name ### Description Get the plugin's filename. If the plugin was ghosted when it was loaded, this filename will be without the .ghost suffix, unless the game is OpenMW, in which case ghosted plugins are not supported. ### Method GET ### Endpoint /plugin/name ### Parameters None ### Request Example None ### Response #### Success Response (200) - **&str** - The plugin's filename. #### Response Example ```json { "name": "example.esp" } ``` ``` -------------------------------- ### pub fn constraint(&self) -> Option<&str> Source: https://docs.rs/libloot/latest/libloot/metadata/struct.File.html Gets the constraint string. ```APIDOC ## pub fn constraint(&self) -> Option<&str> ### Description Gets the constraint string. ### Returns - **Option<&str>** - The constraint string if set, otherwise None. ``` -------------------------------- ### pub fn tags(&self) -> &[Tag] Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Gets the plugin's Bash Tag suggestions. ```APIDOC ## pub fn tags(&self) -> &[Tag] ### Description Gets the plugin's Bash Tag suggestions. ### Method tags ### Return Value &[Tag] - A slice of tag objects. ``` -------------------------------- ### pub fn display_name(&self) -> Option<&str> Source: https://docs.rs/libloot/latest/libloot/metadata/struct.File.html Gets the display name of the file. ```APIDOC ## pub fn display_name(&self) -> Option<&str> ### Description Gets the display name of the file. ### Returns - **Option<&str>** - The display name if set, otherwise None. ``` -------------------------------- ### pub fn name(&self) -> &Filename Source: https://docs.rs/libloot/latest/libloot/metadata/struct.File.html Gets the name of the file, which may actually be a path. ```APIDOC ## pub fn name(&self) -> &Filename ### Description Gets the name of the file, which may actually be a path. ### Returns - **&Filename** - The name of the file. ``` -------------------------------- ### Test setup with plugin tag strings Source: https://docs.rs/libloot/latest/src/libloot/plugin/mod.rs.html Part of a test that constructs a list of tag strings and passes them to a function. The exact purpose is not fully visible in the snippet, but it appears to be setting up a collection of plugin tags for a test assertion. ```rust "C.Owner".into(), "C.Water".into(), "Delev".into(), "Graphics".into(), "Invent".into(), "Names".into(), "Relev".into(), "Sound".into(), "Stats".into(), ], tags ); } ``` -------------------------------- ### pub fn clean_info(&self) -> &[PluginCleaningData] Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Gets the plugin's clean plugin information. ```APIDOC ## pub fn clean_info(&self) -> &[PluginCleaningData] ### Description Gets the plugin's clean plugin information. ### Method clean_info ### Return Value &[PluginCleaningData] - A slice of clean cleaning data objects. ``` -------------------------------- ### sort_plugins Source: https://docs.rs/libloot/latest/libloot/struct.Game.html Calculates a new load order for the game's installed plugins and returns the sorted order. It uses metadata from the masterlist and userlist if loaded, and the loaded data of each plugin. ```APIDOC ## sort_plugins ### Description Calculates a new load order for the game's installed plugins (including inactive plugins) and returns the sorted order. This pulls metadata from the masterlist and userlist if they are loaded, and uses the loaded data of each plugin. No changes are applied to the load order used by the game. ### Method pub fn sort_plugins ### Signature pub fn sort_plugins(&self, plugin_names: &[&str]) -> Result, SortPluginsError> ### Parameters - **plugin_names** (&[&str]) - Required - The list of plugin filenames in their current load order. All given plugins must have been already loaded using `Game::load_plugins` or `Game::load_plugin_headers`. ### Returns - **Result, SortPluginsError>** - The sorted load order as a vector of plugin filenames. ### Notes - This function does not load or evaluate the masterlist or userlist. - The order in which plugins are listed in `plugin_filenames` is used as their current load order. ``` -------------------------------- ### should_add_edges_from_only_the_last_installed_early_loader_to_all_non_early_loader_plugins Source: https://docs.rs/libloot/latest/src/libloot/sorting/plugins.rs.html Test that edges are added from only the last installed early loader to all non-early loader plugins. Asserts that edges exist from a to b, b to d, and b to e, but not from a to d. ```rust let fixture = Fixture::with_plugins(&[PLUGIN_A, PLUGIN_B, PLUGIN_D, PLUGIN_E]); let mut graph = PluginsGraph::::new(); let a = graph.add_node(fixture.sorting_data(PLUGIN_A)); let b = graph.add_node(fixture.sorting_data(PLUGIN_B)); let d = graph.add_node(fixture.sorting_data(PLUGIN_D)); let e = graph.add_node(fixture.sorting_data(PLUGIN_E)); graph.add_early_loading_plugin_edges(&[ PLUGIN_A.into(), PLUGIN_B.into(), PLUGIN_C.into(), ]); assert!(graph.inner.contains_edge(a, b)); assert!(graph.inner.contains_edge(b, d)); assert!(graph.inner.contains_edge(b, e)); assert!(!graph.inner.contains_edge(a, d)); ``` -------------------------------- ### Get Windows file information Source: https://docs.rs/libloot/latest/src/libloot/archive/find.rs.html Opens a file and retrieves its BY_HANDLE_FILE_INFORMATION using the Windows API GetFileInformationByHandle. Returns None if the file cannot be opened or the call fails. The unsafe block is justified because there is no safe alternative for this data. ```rust #[cfg(windows)] fn get_file_info(file_path: &Path) -> Option { use std::os::windows::io::AsRawHandle; use windows_sys::Win32::Storage::FileSystem::GetFileInformationByHandle; let Ok(file) = std::fs::File::open(file_path) else { return None; }; let mut info = BY_HANDLE_FILE_INFORMATION::default(); #[expect( unsafe_code, reason = "There is currently no way to get this data safely" )] // SAFETY: This is safe because the file handles and the info struct pointers are all valid until this function exits. let result = unsafe { GetFileInformationByHandle(file.as_raw_handle(), &raw mut info) }; (result != 0).then_some(info) } ``` -------------------------------- ### PluginCleaningData::detail Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginCleaningData.html Gets any additional informative message content supplied with the cleaning data, eg. a link to a cleaning guide or information on wild edits or manual cleaning steps. ```APIDOC ## PluginCleaningData::detail ### Description Gets any additional informative message content supplied with the cleaning data, eg. a link to a cleaning guide or information on wild edits or manual cleaning steps. ### Method `pub fn detail(&self) -> &[MessageContent]` ### Parameters None. ### Returns - **&[MessageContent]** - A slice of message content. ``` -------------------------------- ### Test replace_prelude replaces prelude at start Source: https://docs.rs/libloot/latest/src/libloot/metadata/metadata_document.rs.html Tests that replace_prelude replaces a prelude at the start of the masterlist. Asserts the resulting masterlist matches the expected result and that meta start_line is 2 and end_line is 5. ```rust let prelude = "globals: - type: note content: A message. "; let masterlist = "prelude: a: b plugins: - name: a.esp "; let result = replace_prelude(masterlist.into(), prelude).unwrap(); let expected_result = "prelude: globals: - type: note content: A message. plugins: - name: a.esp "; assert_eq!(expected_result, result.masterlist); assert_eq!(2, result.meta.as_ref().unwrap().start_line); assert_eq!(5, result.meta.as_ref().unwrap().end_line); ``` -------------------------------- ### pub fn new(name: String) -> Self Source: https://docs.rs/libloot/latest/libloot/metadata/struct.File.html Creates a new File instance with the given name, which can be a relative path. ```APIDOC ## pub fn new(name: String) -> Self ### Description Creates a new File instance with the given name, which can be a relative path. ### Parameters - **name** (String) - Required - The name of the file, can be a relative path. ### Returns - **Self** - The new File instance. ``` -------------------------------- ### File::constraint Source: https://docs.rs/libloot/latest/src/libloot/metadata/file.rs.html Gets the constraint string. ```APIDOC ## File::constraint ### Description Gets the constraint string. ### Method `pub fn constraint(&self) -> Option<&str>` ### Returns - **Option<&str>** - The constraint string if set, otherwise None. ### Example ```rust let file = File::new("file.nif".to_string()) .with_constraint("some_constraint".to_string()); let constraint = file.constraint(); ``` ``` -------------------------------- ### File::condition Source: https://docs.rs/libloot/latest/src/libloot/metadata/file.rs.html Gets the condition string. ```APIDOC ## File::condition ### Description Gets the condition string. ### Method `pub fn condition(&self) -> Option<&str>` ### Returns - **Option<&str>** - The condition string if set, otherwise None. ### Example ```rust let file = File::new("file.nif".to_string()) .with_condition("some_condition".to_string()); let condition = file.condition(); ``` ``` -------------------------------- ### masters Source: https://docs.rs/libloot/latest/libloot/struct.Plugin.html Get the plugin's masters. ```APIDOC ## masters ### Description Get the plugin's masters. ### Method GET ### Endpoint /plugin/masters ### Parameters None ### Request Example None ### Response #### Success Response (200) - **Vec** - A list of master plugin filenames. #### Response Example ```json { "masters": ["master1.esm", "master2.esm"] } ``` ``` -------------------------------- ### pub fn set_load_after_files(&mut self, files: Vec) Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Sets the plugins that the plugin must load after. ```APIDOC ## pub fn set_load_after_files(&mut self, files: Vec) ### Description Sets the plugins that the plugin must load after. ### Method set_load_after_files ### Parameters - **files** (Vec) - Required - The files to load after. ``` -------------------------------- ### pub fn as_yaml(&self) -> String Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Serialises the plugin metadata as YAML. ```APIDOC ## pub fn as_yaml(&self) -> String ### Description Serialises the plugin metadata as YAML. ### Method as_yaml ### Return Value String - The YAML representation of the metadata. ``` -------------------------------- ### Message::condition Source: https://docs.rs/libloot/latest/libloot/metadata/struct.Message.html Gets the condition string. ```APIDOC ## Message::condition ### Description Gets the condition string. ### Method `pub fn condition(&self) -> Option<&str>` ### Parameters - **self** (`&Message`) - Required - The message instance. ### Returns - `Option<&str>` - The condition string if present, otherwise `None`. ``` -------------------------------- ### Database::load_masterlist_with_prelude Source: https://docs.rs/libloot/latest/src/libloot/database/mod.rs.html Loads the masterlist from the given path, using the prelude at the given path. Replaces any existing masterlist and prelude data. ```APIDOC ## load_masterlist_with_prelude ### Description Loads the masterlist from the given path, using the prelude at the given path. Replaces any existing data that was previously loaded from a masterlist and prelude. ### Method load_masterlist_with_prelude ### Parameters - **masterlist_path** (`&Path`) - Required - The path to the masterlist file. - **prelude_path** (`&Path`) - Required - The path to the prelude file. ### Returns - `Result<(), LoadMetadataError>` - Ok if successful, otherwise an error. ``` -------------------------------- ### Message::content Source: https://docs.rs/libloot/latest/libloot/metadata/struct.Message.html Gets the message content. ```APIDOC ## Message::content ### Description Gets the message content. ### Method `pub fn content(&self) -> &[MessageContent]` ### Parameters - **self** (`&Message`) - Required - The message instance. ### Returns - `&[MessageContent]` - A slice of `MessageContent` objects. ``` -------------------------------- ### Writing user metadata and minimal list Source: https://docs.rs/libloot/latest/src/libloot/database/mod.rs.html Methods to write user metadata and a minimal list containing only Bash Tag suggestions and dirty info. Both validate the output path before writing. ```rust /// Writes a metadata file containing all loaded user-added metadata. /// /// If `output_path` already exists, it will be written if `overwrite` is /// `true`, otherwise no data will be written. pub fn write_user_metadata( &self, output_path: &Path, options: &MetadataWriteOptions, ) -> Result<(), WriteMetadataError> { validate_write_path(output_path, options)?; self.userlist.save(output_path, options) } /// Writes a metadata file that only contains plugin Bash Tag suggestions /// and dirty info. /// /// If `output_path` already exists, it will be written if `overwrite` is /// `true`, otherwise no data will be written. pub fn write_minimal_list( &self, output_path: &Path, options: &MetadataWriteOptions, ) -> Result<(), WriteMetadataError> { validate_write_path(output_path, options)?; let mut doc = MetadataDocument::default(); for plugin in self.masterlist.ordered_plugins_iter() { let mut minimal_plugin = PluginMetadata::with_same_name(plugin); minimal_plugin.set_tags(plugin.tags().to_vec()); minimal_plugin.set_dirty_info(plugin.dirty_info().to_vec()); doc.set_plugin_metadata(minimal_plugin); } doc.save(output_path, options) } ``` -------------------------------- ### Message::message_type Source: https://docs.rs/libloot/latest/libloot/metadata/struct.Message.html Gets the message type. ```APIDOC ## Message::message_type ### Description Gets the message type. ### Method `pub fn message_type(&self) -> MessageType` ### Parameters - **self** (`&Message`) - Required - The message instance. ### Returns - `MessageType` - The message type. ``` -------------------------------- ### pub fn new(name: &str) -> Result Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Creates a PluginMetadata value with no metadata for a plugin with the given filename. This is a constructor for initializing a PluginMetadata object. ```APIDOC ## pub fn new(name: &str) -> Result ### Description Creates a value with no metadata for a plugin with the given filename. ### Method new ### Parameters - **name** (&str) - Required - The filename of the plugin. ### Return Value - Result - A PluginMetadata instance or a regex error if the name is invalid. ``` -------------------------------- ### PluginCleaningData::condition Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginCleaningData.html Gets the condition string. ```APIDOC ## PluginCleaningData::condition ### Description Gets the condition string. ### Method `pub fn condition(&self) -> Option<&str>` ### Parameters None. ### Returns - **Option<&str>** - The condition string if present. ``` -------------------------------- ### Game::new Source: https://docs.rs/libloot/latest/libloot/struct.Game.html Initializes a new game handle for the specified game type and path. Attempts to look up the game's local data path, which may fail in some situations. ```APIDOC ## Game::new ### Description Initializes a new game handle for the specified game type and path. Attempts to look up the game's local data path, which may fail in some situations. ### Method Constructor ### Parameters - `game_type` (GameType) - Required - The game type to create the handle for. - `game_path` (&Path) - Required - The relative or absolute path to the directory containing the game's executable. ### Returns - `Result` - The new game handle or an error if creation fails. ### Remarks If the local data path lookup fails, use `Game::with_local_path` to provide the local path explicitly. ``` -------------------------------- ### File::display_name Source: https://docs.rs/libloot/latest/src/libloot/metadata/file.rs.html Gets the display name of the file. ```APIDOC ## File::display_name ### Description Gets the display name of the file. ### Method `pub fn display_name(&self) -> Option<&str>` ### Returns - **Option<&str>** - The display name if set, otherwise None. ### Example ```rust let file = File::new("file.nif".to_string()) .with_display_name("Example File".to_string()); let display_name = file.display_name(); ``` ``` -------------------------------- ### MetadataWriteOptions::anchor_file_strings Source: https://docs.rs/libloot/latest/libloot/struct.MetadataWriteOptions.html Gets the current value of the `anchor_file_strings` option. ```APIDOC ## MetadataWriteOptions::anchor_file_strings ### Description Gets the current value of the `anchor_file_strings` option. ### Method anchor_file_strings ### Signature `pub fn anchor_file_strings(&self) -> bool` ### Parameters None ### Returns - **bool** - The current value of the `anchor_file_strings` option. ``` -------------------------------- ### Add group edges to PluginsGraph and verify expected edges Source: https://docs.rs/libloot/latest/src/libloot/sorting/plugins.rs.html Builds a PluginsGraph with six plugins and adds group edges from a pre-built groups graph, then asserts the expected edges and that no cycles exist. The comment shows the expected ordering: D.esp -> B.esp -> C.esp -> E.esp, A.esp -> F.esp -> B.esp, and A.esp -> E.esp. ```rust let mut graph = PluginsGraph::::new(); let a = graph.add_node(fixture.group_sorting_data(PLUGIN_A, "A")); let b = graph.add_node(fixture.group_sorting_data(PLUGIN_B, "B")); let c = graph.add_node(fixture.group_sorting_data(PLUGIN_C, "C")); let d = graph.add_node(fixture.group_sorting_data(PLUGIN_D, "D")); let e = graph.add_node(fixture.group_sorting_data(PLUGIN_E, "E")); let f = graph.add_node(fixture.group_sorting_data(PLUGIN_F, "F")); graph.add_edge(f, b, EdgeType::Master); graph.add_group_edges(&groups_graph).unwrap(); // Should be D.esp -> B.esp -> C.esp -> E.esp // A.esp -> F.esp ----------> B.esp // A.esp -------------------------------------> E.esp assert!(graph.inner.contains_edge(d, b)); assert!(graph.inner.contains_edge(b, c)); assert!(graph.inner.contains_edge(c, e)); assert!(graph.inner.contains_edge(a, f)); assert!(graph.inner.contains_edge(a, e)); assert!(graph.inner.contains_edge(f, b)); assert!(graph.check_for_cycles().is_ok()); ``` -------------------------------- ### MetadataWriteOptions::write_common_section Source: https://docs.rs/libloot/latest/libloot/struct.MetadataWriteOptions.html Gets the current value of the `write_common_section` option. ```APIDOC ## MetadataWriteOptions::write_common_section ### Description Gets the current value of the `write_common_section` option. ### Method write_common_section ### Signature `pub fn write_common_section(&self) -> bool` ### Parameters None ### Returns - **bool** - The current value of the `write_common_section` option. ``` -------------------------------- ### MetadataWriteOptions::write_anchors Source: https://docs.rs/libloot/latest/libloot/struct.MetadataWriteOptions.html Gets the current value of the `write_anchors` option. ```APIDOC ## MetadataWriteOptions::write_anchors ### Description Gets the current value of the `write_anchors` option. ### Method write_anchors ### Signature `pub fn write_anchors(&self) -> bool` ### Parameters None ### Returns - **bool** - The current value of the `write_anchors` option. ``` -------------------------------- ### MetadataWriteOptions::truncate Source: https://docs.rs/libloot/latest/libloot/struct.MetadataWriteOptions.html Gets the current value of the `truncate` option. ```APIDOC ## MetadataWriteOptions::truncate ### Description Gets the current value of the `truncate` option. ### Method truncate ### Signature `pub fn truncate(&self) -> bool` ### Parameters None ### Returns - **bool** - The current value of the `truncate` option. ``` -------------------------------- ### File::new Source: https://docs.rs/libloot/latest/src/libloot/metadata/file.rs.html Creates a new File with the given name, which can be a relative path. ```APIDOC ## File::new ### Description Creates a new File with the given name, which can be a relative path. ### Method `pub fn new(name: String) -> Self` ### Parameters - **name** (String) - Required - The name of the file, which can be a relative path. ### Returns - **Self** - A new File instance. ### Example ```rust let file = File::new("meshes/example.nif".to_string()); ``` ``` -------------------------------- ### File::name Source: https://docs.rs/libloot/latest/src/libloot/metadata/file.rs.html Gets the name of the file, which may actually be a path. ```APIDOC ## File::name ### Description Gets the name of the file, which may actually be a path. ### Method `pub fn name(&self) -> &Filename` ### Returns - **&Filename** - A reference to the file's name. ### Example ```rust let file = File::new("meshes/example.nif".to_string()); let name = file.name(); ``` ``` -------------------------------- ### Test is_light_plugin for ESL extension across game types Source: https://docs.rs/libloot/latest/src/libloot/plugin/mod.rs.html Copies a blank ESP to a temporary file with .esl extension, creates Plugin instances for master, plugin, and light, then asserts is_light_plugin() is true only for Fallout4, Fallout4VR, SkyrimSE, SkyrimVR, and Starfield. ```rust let tmp_dir = tempdir().unwrap(); let data_path = source_plugins_path(game_type); let light_path = tmp_dir.path().join(BLANK_ESL); std::fs::copy(data_path.join(BLANK_ESP), &light_path).unwrap(); let master = Plugin::new( game_type, &GameCache::default(), &data_path.join(blank_esm(game_type)), LoadScope::HeaderOnly, ) .unwrap(); let plugin = Plugin::new( game_type, &GameCache::default(), &data_path.join(BLANK_ESP), LoadScope::HeaderOnly, ) .unwrap(); let light = Plugin::new( game_type, &GameCache::default(), &light_path, LoadScope::HeaderOnly, ) .unwrap(); assert!(!master.is_light_plugin()); assert!(!plugin.is_light_plugin()); if matches!( game_type, GameType::Fallout4 | GameType::Fallout4VR | GameType::SkyrimSE | GameType::SkyrimVR | GameType::Starfield ) { assert!(light.is_light_plugin()); } else { assert!(!light.is_light_plugin()); } ``` -------------------------------- ### Vertex::name Source: https://docs.rs/libloot/latest/libloot/struct.Vertex.html Gets the name of the plugin or group that the vertex represents. ```APIDOC ## Vertex::name ### Description Gets the name of the plugin or group that the vertex represents. ### Method `pub fn name(&self) -> &str` ### Returns - `&str` - The name of the plugin or group. ``` -------------------------------- ### PluginCleaningData::deleted_navmesh_count Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginCleaningData.html Gets the number of deleted navmeshes found in the plugin. ```APIDOC ## PluginCleaningData::deleted_navmesh_count ### Description Gets the number of deleted navmeshes found in the plugin. ### Method `pub fn deleted_navmesh_count(&self) -> u32` ### Parameters None. ### Returns - **u32** - The number of deleted navmeshes. ``` -------------------------------- ### Filename::new Source: https://docs.rs/libloot/latest/libloot/metadata/struct.Filename.html Creates a new Filename instance from a given string. This is the primary constructor for the Filename type. ```APIDOC ## Filename::new ### Description Creates a new Filename value using the given string. ### Method new ### Signature pub fn new(s: String) -> Self ### Parameters - **s** (String) - Required - The string to create the Filename from. ### Returns - **Filename** - A new Filename instance wrapping the provided string. ``` -------------------------------- ### PluginCleaningData::deleted_reference_count Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginCleaningData.html Gets the number of deleted references found in the plugin. ```APIDOC ## PluginCleaningData::deleted_reference_count ### Description Gets the number of deleted references found in the plugin. ### Method `pub fn deleted_reference_count(&self) -> u32` ### Parameters None. ### Returns - **u32** - The number of deleted references. ``` -------------------------------- ### PluginCleaningData::crc Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginCleaningData.html Gets the CRC that identifies the plugin that the cleaning data is for. ```APIDOC ## PluginCleaningData::crc ### Description Gets the CRC that identifies the plugin that the cleaning data is for. ### Method `pub fn crc(&self) -> u32` ### Parameters None. ### Returns - **u32** - The CRC value. ``` -------------------------------- ### Configure MetadataWriteOptions for anchors and common section Source: https://docs.rs/libloot/latest/src/libloot/metadata/metadata_document.rs.html Sets up a temporary path and MetadataWriteOptions with write_anchors, write_common_section, and anchor_file_strings all true, preparing to save metadata with anchors and a common section. ```rust let tmp_dir = tempdir().unwrap(); let path = tmp_dir.path().join("masterlist.yaml"); let metadata = metadata_with_repeated_values(); let mut options = MetadataWriteOptions::new(); options.set_write_anchors(true); options.set_write_common_section(true); options.set_anchor_file_strings(true); ``` -------------------------------- ### bash_tags Source: https://docs.rs/libloot/latest/libloot/struct.Plugin.html Get any Bash Tags found in the plugin's description field. ```APIDOC ## bash_tags ### Description Get any Bash Tags found in the plugin's description field. ### Method GET ### Endpoint /plugin/bash_tags ### Parameters None ### Request Example None ### Response #### Success Response (200) - **&[String]** - A slice of Bash Tag strings. #### Response Example ```json { "bash_tags": ["Tag1", "Tag2"] } ``` ``` -------------------------------- ### Add group edges with default group and verify expected edges Source: https://docs.rs/libloot/latest/src/libloot/sorting/plugins.rs.html Builds a PluginsGraph with five plugins and adds group edges from a groups graph that includes a default group, then asserts the expected edges and that no cycles exist. The comment shows the expected ordering: A.esp -> B.esp -> E.esp -> C.esp -> D.esp. ```rust let fixture = Fixture::with_plugins(&[PLUGIN_A, PLUGIN_B, PLUGIN_B1, PLUGIN_B2, PLUGIN_C, PLUGIN_D]); let groups_graph = build_groups_graph( &[ Group::new("A".into()), Group::new("B".into()).with_after_groups(vec!["A".into()]), Group::new("C".into()).with_after_groups(vec!["A".into()]), Group::new("D".into()).with_after_groups(vec!["C".into()]), Group::new("E".into()).with_after_groups(vec!["B".into(), "D".into()]), Group::default(), ], &[], ) .unwrap(); let mut graph = PluginsGraph::::new(); let a = graph.add_node(fixture.group_sorting_data(PLUGIN_A, "A")); let b = graph.add_node(fixture.group_sorting_data(PLUGIN_B, "B")); let c = graph.add_node(fixture.group_sorting_data(PLUGIN_C, "C")); let d = graph.add_node(fixture.group_sorting_data(PLUGIN_D, "D")); let e = graph.add_node(fixture.group_sorting_data(PLUGIN_E, "E")); graph.add_edge(e, c, EdgeType::Master); graph.add_group_edges(&groups_graph).unwrap(); // Should be A.esp -> B.esp -> E.esp -> C.esp -> D.esp assert!(graph.inner.contains_edge(a, b)); assert!(graph.inner.contains_edge(b, e)); assert!(graph.inner.contains_edge(e, c)); assert!(graph.inner.contains_edge(c, d)); assert!(graph.check_for_cycles().is_ok()); ``` -------------------------------- ### pub fn locations(&self) -> &[Location] Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Gets the locations at which this plugin can be found. ```APIDOC ## pub fn locations(&self) -> &[Location] ### Description Gets the locations at which this plugin can be found. ### Method locations ### Return Value &[Location] - A slice of location objects. ``` -------------------------------- ### pub fn messages(&self) -> &[Message] Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginMetadata.html Gets the plugin's messages. ```APIDOC ## pub fn messages(&self) -> &[Message] ### Description Gets the plugin's messages. ### Method messages ### Return Value &[Message] - A slice of message objects. ``` -------------------------------- ### pub fn with_constraint(self, constraint: String) -> Self Source: https://docs.rs/libloot/latest/libloot/metadata/struct.File.html Sets the constraint string for the file. ```APIDOC ## pub fn with_constraint(self, constraint: String) -> Self ### Description Sets the constraint string for the file. ### Parameters - **constraint** (String) - Required - The constraint string to set. ### Returns - **Self** - The File instance with the constraint set. ``` -------------------------------- ### Test whole plugin scope reads assets from archives Source: https://docs.rs/libloot/latest/src/libloot/plugin/mod.rs.html Sets up a game cache with archive paths for Blank.bsa and Blank - Main.ba2, then creates a plugin with WholePlugin scope. For Morrowind, OpenMW, and Starfield, expects no archive loading and zero assets; otherwise expects one asset and overlap. ```rust let data_path = source_plugins_path(game_type); let path = data_path.join(BLANK_ESP); let mut cache = GameCache::default(); cache.set_archive_paths(vec![ data_path.join("Blank.bsa"), data_path.join("Blank - Main.ba2"), ]); let plugin = Plugin::new(game_type, &cache, &path, LoadScope::WholePlugin).unwrap(); if matches!( game_type, GameType::Morrowind | GameType::OpenMW | GameType::Starfield ) { // The Starfield test data doesn't include a BA2 file. assert!(!plugin.loads_archive()); assert_eq!(0, plugin.asset_count()); assert!(!plugin.do_assets_overlap(&plugin)); } else { assert!(plugin.loads_archive()); assert_eq!(1, plugin.asset_count()); assert!(plugin.do_assets_overlap(&plugin)); } ``` -------------------------------- ### pub fn condition(&self) -> Option<&str> Source: https://docs.rs/libloot/latest/libloot/metadata/struct.File.html Gets the condition string. ```APIDOC ## pub fn condition(&self) -> Option<&str> ### Description Gets the condition string. ### Returns - **Option<&str>** - The condition string if set, otherwise None. ``` -------------------------------- ### Test write_minimal_list output content Source: https://docs.rs/libloot/latest/src/libloot/database/mod.rs.html Loads the masterlist, writes a minimal list, and asserts the output matches the expected YAML content. The comment notes that plugin entries are unordered, so the exact order in the expected string is not guaranteed. ```rust let fixture = Fixture::new(GameType::Oblivion); let mut database = fixture.database(); let output_path = fixture.inner.local_path.join("minimal.yaml"); database.load_masterlist(&fixture.metadata_path).unwrap(); assert!( database .write_minimal_list(&output_path, &MetadataWriteOptions::new()) .is_ok() ); let content = std::fs::read_to_string(output_path).unwrap(); // Plugin entries are unordered. let expected_content = "plugins: - name: 'Blank.esm' tag: - Actors.ACBS - Actors.AIData - -C.Water - name: 'Blank - Different.esm' dirty: - crc: 0x7D22F9DF util: 'TES4Edit' udr: 4 "; assert_eq!(expected_content, content); ``` -------------------------------- ### Vertex::out_edge_type Source: https://docs.rs/libloot/latest/libloot/struct.Vertex.html Gets the type of the edge going from this vertex to the next in the path. ```APIDOC ## Vertex::out_edge_type ### Description Gets the type of the edge going from this vertex to the next in the path. ### Method `pub fn out_edge_type(&self) -> Option` ### Returns - `Option` - The type of the edge, or `None` if no out edge exists. ``` -------------------------------- ### Test: early loader allows blueprint master before non-master (without master A) Source: https://docs.rs/libloot/latest/src/libloot/sorting/plugins.rs.html Sets up a fixture with two plugins, marks B as a blueprint master. Sorting with PLUGIN_B as an early loader should succeed and produce the order [PLUGIN_A, PLUGIN_B]. ```rust let mut fixture = Fixture::with_plugins(&[PLUGIN_A, PLUGIN_B]); let b = fixture.get_plugin_mut(PLUGIN_B); b.is_master = true; b.is_blueprint_plugin = true; let data = vec![ fixture.sorting_data(PLUGIN_A), fixture.sorting_data(PLUGIN_B), ]; let expected = &[PLUGIN_A, PLUGIN_B]; let sorted = sort_plugins(data, &fixture.groups_graph, &[PLUGIN_B.into()]).unwrap(); assert_eq!(expected, sorted.as_slice()); ``` -------------------------------- ### PluginCleaningData::itm_count Source: https://docs.rs/libloot/latest/libloot/metadata/struct.PluginCleaningData.html Gets the number of Identical To Master records found in the plugin. ```APIDOC ## PluginCleaningData::itm_count ### Description Gets the number of Identical To Master records found in the plugin. ### Method `pub fn itm_count(&self) -> u32` ### Parameters None. ### Returns - **u32** - The number of ITM records. ```