diff --git a/cpp/include/loot/database_interface.h b/cpp/include/loot/database_interface.h index 750291cc..fefc2aab 100644 --- a/cpp/include/loot/database_interface.h +++ b/cpp/include/loot/database_interface.h @@ -152,6 +152,15 @@ public: */ virtual std::vector GetUserKnownBashTags() const = 0; + /** + * @brief Sets the known Bash Tags to store in the userlist, overwriting any + * existing definitions there. + * @param bashTags + * The Bash Tag names to set. + */ + virtual void SetUserKnownBashTags( + const std::vector& bashTags) = 0; + /** * @brief Get all general messages listed in the loaded metadata lists. * @param evaluateConditions diff --git a/cpp/src/api/database.cpp b/cpp/src/api/database.cpp index 2c5c3f13..49b8e1e6 100644 --- a/cpp/src/api/database.cpp +++ b/cpp/src/api/database.cpp @@ -70,8 +70,15 @@ std::vector Database::GetKnownBashTags() const { std::vector Database::GetUserKnownBashTags() const { try { - return convert( - database_->user_known_bash_tags()); + return convert(database_->user_known_bash_tags()); + } catch (const ::rust::Error& e) { + std::rethrow_exception(mapError(e)); + } +} + +void Database::SetUserKnownBashTags(const std::vector& bashTags) { + try { + return database_->set_user_known_bash_tags(convert(bashTags)); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } diff --git a/cpp/src/api/database.h b/cpp/src/api/database.h index 0a66dc47..df310d38 100644 --- a/cpp/src/api/database.h +++ b/cpp/src/api/database.h @@ -32,6 +32,8 @@ public: std::vector GetUserKnownBashTags() const override; + void SetUserKnownBashTags(const std::vector& bashTags) override; + std::vector GetGeneralMessages( bool evaluateConditions = false) const override; diff --git a/cpp/src/database.rs b/cpp/src/database.rs index 2ef70771..21e5cf34 100644 --- a/cpp/src/database.rs +++ b/cpp/src/database.rs @@ -120,6 +120,15 @@ impl Database { .to_vec()) } + pub fn set_user_known_bash_tags(&self, bash_tags: Vec) -> Result<(), VerboseError> { + self.0 + .write() + .map_err(DatabaseLockPoisonError::from)? + .set_user_known_bash_tags(bash_tags); + + Ok(()) + } + pub fn general_messages( &self, evaluate_conditions: bool, diff --git a/cpp/src/lib.rs b/cpp/src/lib.rs index e60ae993..334def65 100644 --- a/cpp/src/lib.rs +++ b/cpp/src/lib.rs @@ -272,6 +272,8 @@ mod ffi { pub fn user_known_bash_tags(&self) -> Result>; + pub fn set_user_known_bash_tags(&self, bash_tags: Vec) -> Result<()>; + pub fn general_messages(&self, evaluate_conditions: bool) -> Result>; pub fn groups(&self, include_user_metadata: bool) -> Result>; diff --git a/cpp/src/tests/api/interface/database_interface_test.h b/cpp/src/tests/api/interface/database_interface_test.h index c38b63a3..5a8cd9d1 100644 --- a/cpp/src/tests/api/interface/database_interface_test.h +++ b/cpp/src/tests/api/interface/database_interface_test.h @@ -502,6 +502,23 @@ TEST_P(DatabaseInterfaceTest, EXPECT_EQ(expectedTags, tags); } +TEST_P(DatabaseInterfaceTest, + setUserKnownBashTagsShouldReplaceAllKnownBashTagsInTheUserlist) { + ASSERT_NO_THROW(GenerateMasterlist()); + ASSERT_NO_THROW(GenerateUserlist()); + + ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath)); + ASSERT_NO_THROW(handle_->GetDatabase().LoadUserlist(userlistPath_)); + + std::vector tags({ + "Filter", + }); + + handle_->GetDatabase().SetUserKnownBashTags({"Filter"}); + + EXPECT_EQ(tags, handle_->GetDatabase().GetUserKnownBashTags()); +} + TEST_P(DatabaseInterfaceTest, getGeneralMessagesShouldGetGeneralMessagesFromTheMasterlistAndUserlist) { ASSERT_NO_THROW(GenerateMasterlist()); diff --git a/nodejs/src/database.rs b/nodejs/src/database.rs index 11d11eac..1d3e3993 100644 --- a/nodejs/src/database.rs +++ b/nodejs/src/database.rs @@ -157,6 +157,16 @@ impl Database { .to_vec()) } + #[napi] + pub fn set_user_known_bash_tags(&self, bash_tags: Vec) -> Result<(), VerboseError> { + self.0 + .write() + .map_err(DatabaseLockPoisonError::from)? + .set_user_known_bash_tags(bash_tags); + + Ok(()) + } + #[napi] pub fn general_messages( &self, diff --git a/python/src/database.rs b/python/src/database.rs index cc505341..05f87aad 100644 --- a/python/src/database.rs +++ b/python/src/database.rs @@ -124,6 +124,15 @@ impl Database { .to_vec()) } + pub fn set_user_known_bash_tags(&self, bash_tags: Vec) -> Result<(), VerboseError> { + self.0 + .write() + .map_err(DatabaseLockPoisonError::from)? + .set_user_known_bash_tags(bash_tags); + + Ok(()) + } + pub fn general_messages( &self, evaluate_conditions: bool, diff --git a/src/database/mod.rs b/src/database/mod.rs index 3d09ed58..eb6659a9 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -180,6 +180,12 @@ impl Database { self.userlist.bash_tags() } + /// Sets the known Bash Tags to store in the userlist, replacing any + /// existing values stored there. + pub fn set_user_known_bash_tags(&mut self, bash_tags: Vec) { + self.userlist.set_bash_tags(bash_tags); + } + /// Get all general messages listed in the loaded metadata lists. pub fn general_messages( &self, @@ -914,6 +920,21 @@ plugins: assert_eq!(&["Relev", "Delev"], database.user_known_bash_tags()); } + #[test] + fn set_user_known_bash_tags_should_replace_existing_user_known_bash_tags() { + let fixture = Fixture::new(GameType::Oblivion); + let mut database = fixture.database(); + + let userlist_path = fixture.inner.local_path.join("userlist.yaml"); + std::fs::write(&userlist_path, "bash_tags: [Relev, Delev]").unwrap(); + + database.load_userlist(&userlist_path).unwrap(); + + database.set_user_known_bash_tags(vec!["Filter".to_owned()]); + + assert_eq!(&["Filter"], database.user_known_bash_tags()); + } + mod general_messages { use super::*; diff --git a/src/metadata/metadata_document.rs b/src/metadata/metadata_document.rs index 8c24044d..0e2a8065 100644 --- a/src/metadata/metadata_document.rs +++ b/src/metadata/metadata_document.rs @@ -310,6 +310,10 @@ impl MetadataDocument { } } + pub(crate) fn set_bash_tags(&mut self, bash_tags: Vec) { + self.bash_tags = bash_tags; + } + pub(crate) fn set_groups(&mut self, groups: Vec) { // Ensure that the default group is present. let default_group_exists = groups.iter().any(|g| g.name() == Group::DEFAULT_NAME);