diff --git a/cxx/src/api/convert.cpp b/cxx/src/api/convert.cpp index f2eeae7d..ee48b0b2 100644 --- a/cxx/src/api/convert.cpp +++ b/cxx/src/api/convert.cpp @@ -147,36 +147,21 @@ loot::Vertex convert(const loot::rust::Vertex& vertex) { } ::rust::Box convert(const loot::Group& group) { - auto output = loot::rust::new_group(group.GetName()); - output->set_after_groups(convert(group.GetAfterGroups())); - output->set_description(group.GetDescription()); - - return output; + return loot::rust::new_group( + group.GetName(), group.GetDescription(), convert(group.GetAfterGroups())); } ::rust::Box convert(const loot::File& file) { - auto output = loot::rust::new_file(std::string(file.GetName())); - - if (!file.GetDisplayName().empty()) { - output->set_display_name(file.GetDisplayName()); - } - try { - output->set_detail( - ::rust::Slice(convert(file.GetDetail()))); + return loot::rust::new_file( + std::string(file.GetName()), + file.GetDisplayName(), + file.GetCondition(), + ::rust::Slice(convert(file.GetDetail())), + file.GetConstraint()); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } - - if (file.IsConditional()) { - output->set_condition(file.GetCondition()); - } - - if (!file.GetConstraint().empty()) { - output->set_constraint(file.GetConstraint()); - } - - return output; } loot::rust::MessageType convert(loot::MessageType messageType) { @@ -194,24 +179,17 @@ loot::rust::MessageType convert(loot::MessageType messageType) { ::rust::Box convert( const loot::MessageContent& content) { - auto output = loot::rust::new_message_content(content.GetText()); - output->set_language(content.GetLanguage()); - - return output; + return loot::rust::new_message_content(content.GetText(), + content.GetLanguage()); } ::rust::Box convert(const loot::Message& message) { try { - auto output = loot::rust::multilingual_message( + return loot::rust::multilingual_message( convert(message.GetType()), ::rust::Slice( - convert(message.GetContent()))); - - if (message.IsConditional()) { - output->set_condition(message.GetCondition()); - } - - return output; + convert(message.GetContent())), + message.GetCondition()); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } @@ -222,13 +200,7 @@ loot::rust::MessageType convert(loot::MessageType messageType) { const auto suggestion = tag.IsAddition() ? loot::rust::TagSuggestion::Addition : loot::rust::TagSuggestion::Removal; - auto output = loot::rust::new_tag(tag.GetName(), suggestion); - - if (tag.IsConditional()) { - output->set_condition(tag.GetCondition()); - } - - return output; + return loot::rust::new_tag(tag.GetName(), suggestion, tag.GetCondition()); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } @@ -236,30 +208,21 @@ loot::rust::MessageType convert(loot::MessageType messageType) { ::rust::Box convert( const loot::PluginCleaningData& data) { - auto output = loot::rust::new_plugin_cleaning_data(data.GetCRC(), - data.GetCleaningUtility()); try { - output->set_detail( - ::rust::Slice(convert(data.GetDetail()))); + return loot::rust::new_plugin_cleaning_data( + data.GetCRC(), + data.GetCleaningUtility(), + ::rust::Slice(convert(data.GetDetail())), + data.GetITMCount(), + data.GetDeletedReferenceCount(), + data.GetDeletedNavmeshCount()); } catch (const ::rust::Error& e) { std::rethrow_exception(mapError(e)); } - - output->set_itm_count(data.GetITMCount()); - output->set_deleted_reference_count(data.GetDeletedReferenceCount()); - output->set_deleted_navmesh_count(data.GetDeletedNavmeshCount()); - - return output; } ::rust::Box convert(const loot::Location& location) { - auto output = loot::rust::new_location(location.GetURL()); - - if (!location.GetName().empty()) { - output->set_name(location.GetName()); - } - - return output; + return loot::rust::new_location(location.GetURL(), location.GetName()); } ::rust::Box convert( diff --git a/cxx/src/lib.rs b/cxx/src/lib.rs index 955cf93c..35d52565 100644 --- a/cxx/src/lib.rs +++ b/cxx/src/lib.rs @@ -383,11 +383,16 @@ mod ffi { extern "Rust" { type Message; - pub fn new_message(message_type: MessageType, content: String) -> Result>; + pub fn new_message( + message_type: MessageType, + content: String, + condition: &str, + ) -> Result>; pub fn multilingual_message( message_type: MessageType, contents: &[Box], + condition: &str, ) -> Result>; pub fn message_type(&self) -> MessageType; @@ -396,8 +401,6 @@ mod ffi { pub fn condition(&self) -> &str; - pub fn set_condition(&mut self, condition: String); - pub fn boxed_clone(&self) -> Box; } @@ -406,21 +409,19 @@ mod ffi { pub fn message_content_default_language() -> &'static str; - pub fn new_message_content(text: String) -> Box; + pub fn new_message_content(text: String, language: &str) -> Box; pub fn text(&self) -> &str; pub fn language(&self) -> &str; - pub fn set_language(&mut self, language: String); - pub fn boxed_clone(&self) -> Box; } extern "Rust" { type Group; - pub fn new_group(name: String) -> Box; + pub fn new_group(name: String, description: &str, after_groups: Vec) -> Box; pub fn group_default_name() -> &'static str; @@ -430,11 +431,7 @@ mod ffi { pub fn description(&self) -> &str; - pub fn set_description(&mut self, description: String); - pub fn after_groups(&self) -> &[String]; - - pub fn set_after_groups(&mut self, groups: Vec); } extern "Rust" { @@ -582,25 +579,31 @@ mod ffi { extern "Rust" { type File; - pub fn new_file(name: String) -> Box; + pub fn new_file( + name: String, + display_name: &str, + condition: &str, + detail: &[Box], + constraint: &str, + ) -> Result>; pub fn filename(&self) -> &Filename; pub fn display_name(&self) -> &str; - pub fn set_display_name(&mut self, display_name: String); + // pub fn set_display_name(&mut self, display_name: String); pub fn detail(&self) -> &[MessageContent]; - pub fn set_detail(&mut self, detail: &[Box]) -> Result<()>; + // pub fn set_detail(&mut self, detail: &[Box]) -> Result<()>; pub fn condition(&self) -> &str; - pub fn set_condition(&mut self, condition: String); + // pub fn set_condition(&mut self, condition: String); pub fn constraint(&self) -> &str; - pub fn set_constraint(&mut self, constraint: String); + // pub fn set_constraint(&mut self, constraint: String); pub fn boxed_clone(&self) -> Box; } @@ -618,7 +621,11 @@ mod ffi { extern "Rust" { type Tag; - pub fn new_tag(name: String, suggestion: TagSuggestion) -> Result>; + pub fn new_tag( + name: String, + suggestion: TagSuggestion, + condition: &str, + ) -> Result>; pub fn name(&self) -> &str; @@ -626,8 +633,6 @@ mod ffi { pub fn condition(&self) -> &str; - pub fn set_condition(&mut self, condition: String); - pub fn boxed_clone(&self) -> Box; } @@ -637,42 +642,36 @@ mod ffi { pub fn new_plugin_cleaning_data( crc: u32, cleaning_utility: String, - ) -> Box; + detail: &[Box], + itm_count: u32, + deleted_reference_count: u32, + deleted_navmesh_count: u32, + ) -> Result>; pub fn crc(&self) -> u32; pub fn itm_count(&self) -> u32; - pub fn set_itm_count(&mut self, count: u32); - pub fn deleted_reference_count(&self) -> u32; - pub fn set_deleted_reference_count(&mut self, count: u32); - pub fn deleted_navmesh_count(&self) -> u32; - pub fn set_deleted_navmesh_count(&mut self, count: u32); - pub fn cleaning_utility(&self) -> &str; pub fn detail(&self) -> &[MessageContent]; - pub fn set_detail(&mut self, detail: &[Box]) -> Result<()>; - pub fn boxed_clone(&self) -> Box; } extern "Rust" { type Location; - pub fn new_location(url: String) -> Box; + pub fn new_location(url: String, name: &str) -> Box; pub fn url(&self) -> &str; pub fn name(&self) -> &str; - pub fn set_name(&mut self, name: String); - pub fn boxed_clone(&self) -> Box; } } diff --git a/cxx/src/metadata.rs b/cxx/src/metadata.rs index 6758bb94..e2974289 100644 --- a/cxx/src/metadata.rs +++ b/cxx/src/metadata.rs @@ -68,8 +68,14 @@ impl TryFrom for libloot::metadata::MessageType { #[repr(transparent)] pub struct MessageContent(libloot::metadata::MessageContent); -pub fn new_message_content(text: String) -> Box { - Box::new(MessageContent(libloot::metadata::MessageContent::new(text))) +pub fn new_message_content(text: String, language: &str) -> Box { + let mut content = libloot::metadata::MessageContent::new(text); + + if !language.is_empty() { + content = content.with_language(language.to_owned()); + } + + Box::new(MessageContent(content)) } pub fn message_content_default_language() -> &'static str { @@ -86,8 +92,6 @@ impl MessageContent { pub fn text(&self) -> &str; pub fn language(&self) -> &str; - - pub fn set_language(&mut self, language: String); } } } @@ -128,22 +132,31 @@ pub struct Message(libloot::metadata::Message); pub fn new_message( message_type: MessageType, content: String, + condition: &str, ) -> Result, VerboseError> { - Ok(Box::new(Message(libloot::metadata::Message::new( - message_type.try_into()?, - content, - )))) + let mut message = libloot::metadata::Message::new(message_type.try_into()?, content); + + if !condition.is_empty() { + message = message.with_condition(condition.to_owned()); + } + + Ok(Box::new(Message(message))) } pub fn multilingual_message( message_type: MessageType, contents: &[Box], + condition: &str, ) -> Result, VerboseError> { let contents = to_vec_of_unwrapped(contents); - Ok(Box::new(Message(libloot::metadata::Message::multilingual( - message_type.try_into()?, - contents, - )?))) + + let mut message = libloot::metadata::Message::multilingual(message_type.try_into()?, contents)?; + + if !condition.is_empty() { + message = message.with_condition(condition.to_owned()); + } + + Ok(Box::new(Message(message))) } impl Message { @@ -163,8 +176,6 @@ impl Message { to self.0 { #[into] pub fn message_type(&self) -> MessageType; - - pub fn set_condition(&mut self, condition: String); } } } @@ -190,8 +201,18 @@ impl From> for libloot::metadata::Message { #[repr(transparent)] pub struct Group(libloot::metadata::Group); -pub fn new_group(name: String) -> Box { - Box::new(Group(libloot::metadata::Group::new(name))) +pub fn new_group(name: String, description: &str, after_groups: Vec) -> Box { + let mut group = libloot::metadata::Group::new(name); + + if !description.is_empty() { + group = group.with_description(description.to_owned()); + } + + if !after_groups.is_empty() { + group = group.with_after_groups(after_groups); + } + + Box::new(Group(group)) } pub fn group_default_name() -> &'static str { @@ -211,11 +232,7 @@ impl Group { to self.0 { pub fn name(&self) -> &str; - pub fn set_description(&mut self, description: String); - pub fn after_groups(&self) -> &[String]; - - pub fn set_after_groups(&mut self, groups: Vec); } } } @@ -374,8 +391,32 @@ impl From> for Optional { #[repr(transparent)] pub struct File(libloot::metadata::File); -pub fn new_file(name: String) -> Box { - Box::new(File(libloot::metadata::File::new(name))) +pub fn new_file( + name: String, + display_name: &str, + condition: &str, + detail: &[Box], + constraint: &str, +) -> Result, VerboseError> { + let mut file = libloot::metadata::File::new(name); + + if !display_name.is_empty() { + file = file.with_display_name(display_name.to_owned()); + } + + if !condition.is_empty() { + file = file.with_condition(condition.to_owned()); + } + + if !detail.is_empty() { + file = file.with_detail(to_vec_of_unwrapped(detail))?; + } + + if !constraint.is_empty() { + file = file.with_constraint(constraint.to_owned()); + } + + Ok(Box::new(File(file))) } impl File { @@ -387,34 +428,34 @@ impl File { self.0.display_name().unwrap_or("") } - pub fn set_display_name(&mut self, display_name: String) { - self.0.set_display_name(display_name); - } + // pub fn set_display_name(&mut self, display_name: String) { + // self.0.set_display_name(display_name); + // } pub fn detail(&self) -> &[MessageContent] { MessageContent::wrap_slice(self.0.detail()) } - pub fn set_detail(&mut self, detail: &[Box]) -> Result<(), VerboseError> { - self.0.set_detail(to_vec_of_unwrapped(detail))?; - Ok(()) - } + // pub fn set_detail(&mut self, detail: &[Box]) -> Result<(), VerboseError> { + // self.0.set_detail(to_vec_of_unwrapped(detail))?; + // Ok(()) + // } pub fn condition(&self) -> &str { self.0.condition().unwrap_or("") } - pub fn set_condition(&mut self, condition: String) { - self.0.set_condition(condition); - } + // pub fn set_condition(&mut self, condition: String) { + // self.0.set_condition(condition); + // } pub fn constraint(&self) -> &str { self.0.constraint().unwrap_or("") } - pub fn set_constraint(&mut self, constraint: String) { - self.0.set_constraint(constraint); - } + // pub fn set_constraint(&mut self, constraint: String) { + // self.0.set_constraint(constraint); + // } pub fn boxed_clone(&self) -> Box { Box::new(Self(self.0.clone())) @@ -461,11 +502,18 @@ unsafe impl TransparentWrapper for Filename { #[repr(transparent)] pub struct Tag(libloot::metadata::Tag); -pub fn new_tag(name: String, suggestion: TagSuggestion) -> Result, VerboseError> { - Ok(Box::new(Tag(libloot::metadata::Tag::new( - name, - suggestion.try_into()?, - )))) +pub fn new_tag( + name: String, + suggestion: TagSuggestion, + condition: &str, +) -> Result, VerboseError> { + let mut tag = libloot::metadata::Tag::new(name, suggestion.try_into()?); + + if !condition.is_empty() { + tag = tag.with_condition(condition.to_owned()); + } + + Ok(Box::new(Tag(tag))) } impl Tag { @@ -482,8 +530,6 @@ impl Tag { pub fn name(&self) -> &str; pub fn is_addition(&self) -> bool; - - pub fn set_condition(&mut self, condition: String); } } } @@ -515,10 +561,24 @@ impl TryFrom for libloot::metadata::TagSuggestion { #[repr(transparent)] pub struct PluginCleaningData(libloot::metadata::PluginCleaningData); -pub fn new_plugin_cleaning_data(crc: u32, cleaning_utility: String) -> Box { - Box::new(PluginCleaningData( - libloot::metadata::PluginCleaningData::new(crc, cleaning_utility), - )) +pub fn new_plugin_cleaning_data( + crc: u32, + cleaning_utility: String, + detail: &[Box], + itm_count: u32, + deleted_reference_count: u32, + deleted_navmesh_count: u32, +) -> Result, VerboseError> { + let mut data = libloot::metadata::PluginCleaningData::new(crc, cleaning_utility) + .with_itm_count(itm_count) + .with_deleted_reference_count(deleted_reference_count) + .with_deleted_navmesh_count(deleted_navmesh_count); + + if !detail.is_empty() { + data = data.with_detail(to_vec_of_unwrapped(detail))?; + } + + Ok(Box::new(PluginCleaningData(data))) } impl PluginCleaningData { @@ -526,11 +586,6 @@ impl PluginCleaningData { MessageContent::wrap_slice(self.0.detail()) } - pub fn set_detail(&mut self, detail: &[Box]) -> Result<(), VerboseError> { - self.0.set_detail(to_vec_of_unwrapped(detail))?; - Ok(()) - } - pub fn boxed_clone(&self) -> Box { Box::new(Self(self.0.clone())) } @@ -541,16 +596,10 @@ impl PluginCleaningData { pub fn itm_count(&self) -> u32; - pub fn set_itm_count(&mut self, count: u32); - pub fn deleted_reference_count(&self) -> u32; - pub fn set_deleted_reference_count(&mut self, count: u32); - pub fn deleted_navmesh_count(&self) -> u32; - pub fn set_deleted_navmesh_count(&mut self, count: u32); - pub fn cleaning_utility(&self) -> &str; } } @@ -571,8 +620,14 @@ impl From> for libloot::metadata::PluginCleaningData { #[repr(transparent)] pub struct Location(libloot::metadata::Location); -pub fn new_location(url: String) -> Box { - Box::new(Location(libloot::metadata::Location::new(url))) +pub fn new_location(url: String, name: &str) -> Box { + let mut location = libloot::metadata::Location::new(url); + + if !name.is_empty() { + location = location.with_name(name.to_owned()); + } + + Box::new(Location(location)) } impl Location { @@ -587,8 +642,6 @@ impl Location { delegate! { to self.0 { pub fn url(&self) -> &str; - - pub fn set_name(&mut self, name: String); } } } diff --git a/cxx/src/tests/api/internals/main.cpp b/cxx/src/tests/api/internals/main.cpp index dbcf9c75..4a09bb8a 100644 --- a/cxx/src/tests/api/internals/main.cpp +++ b/cxx/src/tests/api/internals/main.cpp @@ -4,7 +4,6 @@ #include "libloot-cxx/src/lib.rs.h" #include "rust/cxx.h" - #include "tests/api/internals/metadata/conditional_metadata_test.h" #include "tests/api/internals/metadata/file_test.h" #include "tests/api/internals/metadata/group_test.h" @@ -43,20 +42,18 @@ TEST(new_game, shouldThrowIfGivenNonsense) { } TEST(Message, creation) { - auto content = new_message_content("a message"); - content->set_language( + auto content = new_message_content( + "a message", ::rust::String(std::string(message_content_default_language()))); - auto message = new_message(MessageType::Say, "message2"); - message->set_condition("invalid condition"); + auto message = new_message(MessageType::Say, "message2", "invalid condition"); std::vector<::rust::Box> contents; contents.push_back(std::move(content)); auto multi_message = multilingual_message( MessageType::Say, - ::rust::Slice>(contents)); - - multi_message->set_condition("invalid condition"); + ::rust::Slice>(contents), + "invalid condition"); EXPECT_EQ(multi_message->content()[0].text(), "a message"); EXPECT_EQ(multi_message->content()[0].language(), "en"); diff --git a/nodejs/src/metadata.rs b/nodejs/src/metadata.rs index 8ec7f881..2b113be4 100644 --- a/nodejs/src/metadata.rs +++ b/nodejs/src/metadata.rs @@ -24,11 +24,11 @@ impl Group { let mut group = libloot::metadata::Group::new(name); if let Some(description) = description { - group.set_description(description); + group = group.with_description(description); } if let Some(after_groups) = after_groups { - group.set_after_groups(after_groups); + group = group.with_after_groups(after_groups); } Self(group) @@ -44,20 +44,10 @@ impl Group { self.0.description() } - #[napi(setter)] - pub fn set_description(&mut self, description: String) { - self.0.set_description(description); - } - #[napi(getter)] pub fn after_groups(&self) -> Vec { self.0.after_groups().to_vec() } - - #[napi(setter)] - pub fn set_after_groups(&mut self, after_groups: Vec) { - self.0.set_after_groups(after_groups); - } } impl From for Group { @@ -89,7 +79,7 @@ impl MessageContent { let mut content = libloot::metadata::MessageContent::new(text); if let Some(language) = language { - content.set_language(language); + content = content.with_language(language); } Self(content) @@ -104,11 +94,6 @@ impl MessageContent { pub fn language(&self) -> &str { self.0.language() } - - #[napi(setter)] - pub fn set_language(&mut self, language: String) { - self.0.set_language(language); - } } impl From for MessageContent { @@ -184,7 +169,7 @@ impl Message { }; if let Some(condition) = condition { - message.set_condition(condition); + message = message.with_condition(condition); } Ok(Self(message)) @@ -204,11 +189,6 @@ impl Message { pub fn condition(&self) -> Option<&str> { self.0.condition() } - - #[napi(setter)] - pub fn set_condition(&mut self, condition: String) { - self.0.set_condition(condition); - } } impl From for Message { @@ -241,20 +221,20 @@ impl File { let mut file = libloot::metadata::File::new(name); if let Some(display_name) = display_name { - file.set_display_name(display_name); + file = file.with_display_name(display_name); } if let Some(detail) = detail { let detail = detail.into_iter().cloned().map(Into::into).collect(); - file.set_detail(detail)?; + file = file.with_detail(detail)?; } if let Some(condition) = condition { - file.set_condition(condition); + file = file.with_condition(condition); } if let Some(constraint) = constraint { - file.set_constraint(constraint); + file = file.with_constraint(constraint); } Ok(Self(file)) @@ -270,42 +250,20 @@ impl File { self.0.display_name() } - #[napi(setter)] - pub fn set_display_name(&mut self, description: String) { - self.0.set_display_name(description); - } - #[napi(getter)] pub fn detail(&self) -> Vec { self.0.detail().iter().cloned().map(Into::into).collect() } - #[napi(setter)] - pub fn set_detail(&mut self, detail: Vec<&MessageContent>) -> Result<(), VerboseError> { - let detail = detail.into_iter().cloned().map(Into::into).collect(); - self.0.set_detail(detail)?; - Ok(()) - } - #[napi(getter)] pub fn condition(&self) -> Option<&str> { self.0.condition() } - #[napi(setter)] - pub fn set_condition(&mut self, condition: String) { - self.0.set_condition(condition); - } - #[napi(getter)] pub fn constraint(&self) -> Option<&str> { self.0.constraint() } - - #[napi(setter)] - pub fn set_constraint(&mut self, constraint: String) { - self.0.set_constraint(constraint); - } } impl From for File { @@ -363,20 +321,20 @@ impl PluginCleaningData { let mut data = libloot::metadata::PluginCleaningData::new(crc, cleaning_utility); if let Some(count) = itm_count { - data.set_itm_count(count); + data = data.with_itm_count(count); } if let Some(count) = deleted_reference_count { - data.set_deleted_reference_count(count); + data = data.with_deleted_reference_count(count); } if let Some(count) = deleted_navmesh_count { - data.set_deleted_navmesh_count(count); + data = data.with_deleted_navmesh_count(count); } if let Some(detail) = detail { let detail = detail.into_iter().cloned().map(Into::into).collect(); - data.set_detail(detail)?; + data = data.with_detail(detail)?; } Ok(Self(data)) @@ -392,31 +350,16 @@ impl PluginCleaningData { self.0.itm_count() } - #[napi(setter)] - pub fn set_itm_count(&mut self, count: u32) { - self.0.set_itm_count(count); - } - #[napi(getter)] pub fn deleted_reference_count(&self) -> u32 { self.0.deleted_reference_count() } - #[napi(setter)] - pub fn set_deleted_reference_count(&mut self, count: u32) { - self.0.set_deleted_reference_count(count); - } - #[napi(getter)] pub fn deleted_navmesh_count(&self) -> u32 { self.0.deleted_navmesh_count() } - #[napi(setter)] - pub fn set_deleted_navmesh_count(&mut self, count: u32) { - self.0.set_deleted_navmesh_count(count); - } - #[napi(getter)] pub fn cleaning_utility(&self) -> &str { self.0.cleaning_utility() @@ -426,13 +369,6 @@ impl PluginCleaningData { pub fn detail(&self) -> Vec { self.0.detail().iter().cloned().map(Into::into).collect() } - - #[napi(setter)] - pub fn set_detail(&mut self, detail: Vec<&MessageContent>) -> Result<(), VerboseError> { - let detail = detail.into_iter().cloned().map(Into::into).collect(); - self.0.set_detail(detail)?; - Ok(()) - } } impl From for PluginCleaningData { @@ -475,7 +411,7 @@ impl Tag { let mut tag = libloot::metadata::Tag::new(name, suggestion.into()); if let Some(condition) = condition { - tag.set_condition(condition); + tag = tag.with_condition(condition); } Self(tag) @@ -495,11 +431,6 @@ impl Tag { pub fn condition(&self) -> Option<&str> { self.0.condition() } - - #[napi(setter)] - pub fn set_condition(&mut self, condition: String) { - self.0.set_condition(condition); - } } impl From for Tag { @@ -526,7 +457,7 @@ impl Location { let mut location = libloot::metadata::Location::new(url); if let Some(name) = name { - location.set_name(name); + location = location.with_name(name); } Self(location) @@ -541,11 +472,6 @@ impl Location { pub fn name(&self) -> Option<&str> { self.0.name() } - - #[napi(setter)] - pub fn set_name(&mut self, name: String) { - self.0.set_name(name); - } } impl From for Location { diff --git a/pyo3/src/metadata.rs b/pyo3/src/metadata.rs index c5b2539e..42b310b0 100644 --- a/pyo3/src/metadata.rs +++ b/pyo3/src/metadata.rs @@ -10,7 +10,7 @@ use crate::error::VerboseError; pub(crate) const NONE_REPR: &str = "None"; -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[repr(transparent)] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct Group(libloot::metadata::Group); @@ -28,11 +28,11 @@ impl Group { let mut group = libloot::metadata::Group::new(name); if let Some(description) = description { - group.set_description(description); + group = group.with_description(description); } if let Some(after_groups) = after_groups { - group.set_after_groups(after_groups); + group = group.with_after_groups(after_groups); } Self(group) @@ -48,21 +48,11 @@ impl Group { self.0.description() } - #[setter] - fn set_description(&mut self, description: String) { - self.0.set_description(description); - } - #[getter] fn after_groups(&self) -> &[String] { self.0.after_groups() } - #[setter] - fn set_after_groups(&mut self, after_groups: Vec) { - self.0.set_after_groups(after_groups); - } - fn __repr__(slf: &Bound<'_, Self>) -> PyResult { let class_name = slf.get_type().qualname()?; let inner = &slf.borrow().0; @@ -74,12 +64,6 @@ impl Group { inner.after_groups().join(",") )) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for Group { @@ -94,7 +78,7 @@ impl From for libloot::metadata::Group { } } -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[repr(transparent)] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] pub struct MessageContent(libloot::metadata::MessageContent); @@ -112,7 +96,7 @@ impl MessageContent { let mut content = libloot::metadata::MessageContent::new(text); if let Some(language) = language { - content.set_language(language); + content = content.with_language(language); } Self(content) @@ -128,11 +112,6 @@ impl MessageContent { self.0.language() } - #[setter] - fn set_language(&mut self, language: String) { - self.0.set_language(language); - } - fn __repr__(slf: &Bound<'_, Self>) -> PyResult { let class_name = slf.get_type().qualname()?; let inner = &slf.borrow().0; @@ -143,12 +122,6 @@ impl MessageContent { inner.language() )) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for MessageContent { @@ -214,7 +187,7 @@ impl From for libloot::metadata::MessageType { } } -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub struct Message(libloot::metadata::Message); @@ -245,7 +218,7 @@ impl Message { }; if let Some(condition) = condition { - message.set_condition(condition); + message = message.with_condition(condition); } Ok(Self(message)) @@ -266,11 +239,6 @@ impl Message { self.0.condition() } - #[setter] - fn set_condition(&mut self, condition: String) { - self.0.set_condition(condition); - } - fn __repr__(slf: &Bound<'_, Self>) -> PyResult { let class_name = slf.get_type().qualname()?; let inner = &slf.borrow().0; @@ -282,12 +250,6 @@ impl Message { inner.condition().unwrap_or(NONE_REPR), )) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for Message { @@ -302,7 +264,7 @@ impl From for libloot::metadata::Message { } } -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub struct File(libloot::metadata::File); @@ -321,20 +283,20 @@ impl File { let mut file = libloot::metadata::File::new(name); if let Some(display_name) = display_name { - file.set_display_name(display_name); + file = file.with_display_name(display_name); } if let Some(detail) = detail { let detail = detail.into_iter().map(Into::into).collect(); - file.set_detail(detail)?; + file = file.with_detail(detail)?; } if let Some(condition) = condition { - file.set_condition(condition); + file = file.with_condition(condition); } if let Some(constraint) = constraint { - file.set_constraint(constraint); + file = file.with_constraint(constraint); } Ok(Self(file)) @@ -350,43 +312,21 @@ impl File { self.0.display_name() } - #[setter] - fn set_display_name(&mut self, description: String) { - self.0.set_display_name(description); - } - #[getter] fn detail(&self) -> Vec { self.0.detail().iter().cloned().map(Into::into).collect() } - #[setter] - fn set_detail(&mut self, detail: Vec) -> Result<(), VerboseError> { - let detail = detail.into_iter().map(Into::into).collect(); - self.0.set_detail(detail)?; - Ok(()) - } - #[getter] fn condition(&self) -> Option<&str> { self.0.condition() } - #[setter] - fn set_condition(&mut self, condition: String) { - self.0.set_condition(condition); - } - #[getter] fn constraint(&self) -> Option<&str> { self.0.constraint() } - #[setter] - fn set_constraint(&mut self, constraint: String) { - self.0.set_constraint(constraint); - } - fn __repr__(slf: &Bound<'_, Self>) -> PyResult { let class_name = slf.get_type().qualname()?; let inner = &slf.borrow().0; @@ -400,12 +340,6 @@ impl File { inner.constraint().unwrap_or(NONE_REPR) )) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for File { @@ -420,7 +354,7 @@ impl From for libloot::metadata::File { } } -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub struct Filename(libloot::metadata::Filename); @@ -441,12 +375,6 @@ impl Filename { let inner = &slf.borrow().0; Ok(format!("{}({})", class_name, inner.as_str(),)) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for Filename { @@ -455,7 +383,7 @@ impl From for Filename { } } -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub struct PluginCleaningData(libloot::metadata::PluginCleaningData); @@ -475,20 +403,20 @@ impl PluginCleaningData { let mut data = libloot::metadata::PluginCleaningData::new(crc, cleaning_utility); if let Some(count) = itm_count { - data.set_itm_count(count); + data = data.with_itm_count(count); } if let Some(count) = deleted_reference_count { - data.set_deleted_reference_count(count); + data = data.with_deleted_reference_count(count); } if let Some(count) = deleted_navmesh_count { - data.set_deleted_navmesh_count(count); + data = data.with_deleted_navmesh_count(count); } if let Some(detail) = detail { let detail = detail.into_iter().map(Into::into).collect(); - data.set_detail(detail)?; + data = data.with_detail(detail)?; } Ok(Self(data)) @@ -504,31 +432,16 @@ impl PluginCleaningData { self.0.itm_count() } - #[setter] - fn set_itm_count(&mut self, count: u32) { - self.0.set_itm_count(count); - } - #[getter] fn deleted_reference_count(&self) -> u32 { self.0.deleted_reference_count() } - #[setter] - fn set_deleted_reference_count(&mut self, count: u32) { - self.0.set_deleted_reference_count(count); - } - #[getter] fn deleted_navmesh_count(&self) -> u32 { self.0.deleted_navmesh_count() } - #[setter] - fn set_deleted_navmesh_count(&mut self, count: u32) { - self.0.set_deleted_navmesh_count(count); - } - #[getter] fn cleaning_utility(&self) -> &str { self.0.cleaning_utility() @@ -539,13 +452,6 @@ impl PluginCleaningData { self.0.detail().iter().cloned().map(Into::into).collect() } - #[setter] - fn set_detail(&mut self, detail: Vec) -> Result<(), VerboseError> { - let detail = detail.into_iter().map(Into::into).collect(); - self.0.set_detail(detail)?; - Ok(()) - } - fn __repr__(slf: &Bound<'_, Self>) -> PyResult { let class_name = slf.get_type().qualname()?; let inner = &slf.borrow().0; @@ -560,12 +466,6 @@ impl PluginCleaningData { repr_message_contents(inner.detail()) )) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for PluginCleaningData { @@ -598,7 +498,7 @@ impl TryFrom for libloot::metadata::TagSuggestion { } } -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub struct Tag(libloot::metadata::Tag); @@ -615,7 +515,7 @@ impl Tag { let mut tag = libloot::metadata::Tag::new(name, suggestion.try_into()?); if let Some(condition) = condition { - tag.set_condition(condition); + tag = tag.with_condition(condition); } Ok(Self(tag)) @@ -636,11 +536,6 @@ impl Tag { self.0.condition() } - #[setter] - fn set_condition(&mut self, condition: String) { - self.0.set_condition(condition); - } - fn __repr__(slf: &Bound<'_, Self>) -> PyResult { let class_name = slf.get_type().qualname()?; let inner = &slf.borrow().0; @@ -657,12 +552,6 @@ impl Tag { inner.condition().unwrap_or(NONE_REPR) )) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for Tag { @@ -677,7 +566,7 @@ impl From for libloot::metadata::Tag { } } -#[pyclass(eq, ord, str = "{0:?}")] +#[pyclass(eq, ord, frozen, hash, str = "{0:?}")] #[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] pub struct Location(libloot::metadata::Location); @@ -690,7 +579,7 @@ impl Location { let mut location = libloot::metadata::Location::new(url); if let Some(name) = name { - location.set_name(name); + location = location.with_name(name); } Self(location) @@ -706,11 +595,6 @@ impl Location { self.0.name() } - #[setter] - fn set_name(&mut self, name: String) { - self.0.set_name(name); - } - fn __repr__(slf: &Bound<'_, Self>) -> PyResult { let class_name = slf.get_type().qualname()?; let inner = &slf.borrow().0; @@ -721,12 +605,6 @@ impl Location { inner.name().unwrap_or(NONE_REPR) )) } - - fn __hash__(&self) -> u64 { - let mut hasher = DefaultHasher::new(); - self.0.hash(&mut hasher); - hasher.finish() - } } impl From for Location { diff --git a/src/metadata/file.rs b/src/metadata/file.rs index 7ac5b102..ca1deec8 100644 --- a/src/metadata/file.rs +++ b/src/metadata/file.rs @@ -38,14 +38,14 @@ impl File { /// CommonMark. #[must_use] pub fn with_display_name(mut self, display_name: String) -> Self { - self.set_display_name(display_name); + self.display_name = Some(display_name.into_boxed_str()); self } /// Set the condition string. #[must_use] pub fn with_condition(mut self, condition: String) -> Self { - self.set_condition(condition); + self.condition = Some(condition.into_boxed_str()); self } @@ -56,14 +56,15 @@ impl File { mut self, detail: Vec, ) -> Result { - self.set_detail(detail)?; + validate_message_contents(&detail)?; + self.detail = detail.into_boxed_slice(); Ok(self) } /// Set the constraint string. #[must_use] pub fn with_constraint(mut self, constraint: String) -> Self { - self.set_constraint(constraint); + self.constraint = Some(constraint.into_boxed_str()); self } @@ -77,13 +78,6 @@ impl File { self.display_name.as_deref() } - /// Set the name to be displayed for the file in messages, formatted using - /// CommonMark. - pub fn set_display_name(&mut self, display_name: String) -> &mut Self { - self.display_name = Some(display_name.into_boxed_str()); - self - } - /// Get the detail message content of the file. /// /// If this file causes an error message to be displayed, the detail message @@ -93,39 +87,15 @@ impl File { &self.detail } - /// Set the detail message content, which may be appended to any messages - /// generated for this file. If multilingual, one language must be - /// [MessageContent::DEFAULT_LANGUAGE]. - pub fn set_detail( - &mut self, - detail: Vec, - ) -> Result<&mut Self, MultilingualMessageContentsError> { - validate_message_contents(&detail)?; - self.detail = detail.into_boxed_slice(); - Ok(self) - } - /// Get the condition string. pub fn condition(&self) -> Option<&str> { self.condition.as_deref() } - /// Set the condition string. - pub fn set_condition(&mut self, condition: String) -> &mut Self { - self.condition = Some(condition.into_boxed_str()); - self - } - /// Get the constraint string. pub fn constraint(&self) -> Option<&str> { self.constraint.as_deref() } - - /// Set the constraint string. - pub fn set_constraint(&mut self, constraint: String) -> &mut Self { - self.constraint = Some(constraint.into_boxed_str()); - self - } } /// Represents a case-insensitive filename. diff --git a/src/metadata/group.rs b/src/metadata/group.rs index 14615acd..f37dfc7c 100644 --- a/src/metadata/group.rs +++ b/src/metadata/group.rs @@ -29,14 +29,14 @@ impl Group { /// Set a description for the group. #[must_use] pub fn with_description(mut self, description: String) -> Self { - self.set_description(description); + self.description = Some(description.into_boxed_str()); self } /// Set the names of the groups that this group loads after. #[must_use] pub fn with_after_groups(mut self, after_groups: Vec) -> Self { - self.set_after_groups(after_groups); + self.after_groups = after_groups.into_boxed_slice(); self } @@ -53,22 +53,10 @@ impl Group { self.description.as_deref() } - /// Set a description for the group. - pub fn set_description(&mut self, description: String) -> &mut Self { - self.description = Some(description.into_boxed_str()); - self - } - /// Get the names of the groups that this group loads after. pub fn after_groups(&self) -> &[String] { &self.after_groups } - - /// Set the names of the groups that this group loads after. - pub fn set_after_groups(&mut self, after_groups: Vec) -> &mut Self { - self.after_groups = after_groups.into_boxed_slice(); - self - } } impl std::default::Default for Group { diff --git a/src/metadata/location.rs b/src/metadata/location.rs index 606f2eda..86348ddf 100644 --- a/src/metadata/location.rs +++ b/src/metadata/location.rs @@ -25,7 +25,7 @@ impl Location { /// Set a name for the URL, eg. the page or site name. #[must_use] pub fn with_name(mut self, name: String) -> Self { - self.set_name(name); + self.name = Some(name.into_boxed_str()); self } @@ -38,12 +38,6 @@ impl Location { pub fn name(&self) -> Option<&str> { self.name.as_deref() } - - /// Set a name for the URL, eg. the page or site name. - pub fn set_name(&mut self, name: String) -> &mut Self { - self.name = Some(name.into_boxed_str()); - self - } } impl TryFromYaml for Location { diff --git a/src/metadata/message.rs b/src/metadata/message.rs index 19f1bb15..0a780661 100644 --- a/src/metadata/message.rs +++ b/src/metadata/message.rs @@ -64,7 +64,7 @@ impl MessageContent { /// Set the language code to the given value. #[must_use] pub fn with_language(mut self, language: String) -> Self { - self.set_language(language); + self.language = language.into_boxed_str(); self } @@ -77,12 +77,6 @@ impl MessageContent { pub fn language(&self) -> &str { &self.language } - - /// Set the language code to the given value. - pub fn set_language(&mut self, language: String) -> &mut Self { - self.language = language.into_boxed_str(); - self - } } impl std::default::Default for MessageContent { @@ -196,7 +190,7 @@ impl Message { /// Set the condition string. #[must_use] pub fn with_condition(mut self, condition: String) -> Self { - self.set_condition(condition); + self.condition = Some(condition.into_boxed_str()); self } @@ -214,12 +208,6 @@ impl Message { pub fn condition(&self) -> Option<&str> { self.condition.as_deref() } - - /// Set the condition string. - pub fn set_condition(&mut self, condition: String) -> &mut Self { - self.condition = Some(condition.into_boxed_str()); - self - } } pub(crate) fn validate_message_contents( diff --git a/src/metadata/plugin_cleaning_data.rs b/src/metadata/plugin_cleaning_data.rs index ee3f28ee..7dac15ed 100644 --- a/src/metadata/plugin_cleaning_data.rs +++ b/src/metadata/plugin_cleaning_data.rs @@ -40,21 +40,21 @@ impl PluginCleaningData { /// Set the number of Identical To Master records found in the plugin. #[must_use] pub fn with_itm_count(mut self, itm_count: u32) -> Self { - self.set_itm_count(itm_count); + self.itm_count = itm_count; self } /// Set the number of deleted references found in the plugin. #[must_use] pub fn with_deleted_reference_count(mut self, deleted_reference_count: u32) -> Self { - self.set_deleted_reference_count(deleted_reference_count); + self.deleted_reference_count = deleted_reference_count; self } /// Set the number of deleted navmeshes found in the plugin. #[must_use] pub fn with_deleted_navmesh_count(mut self, deleted_navmesh_count: u32) -> Self { - self.set_deleted_navmesh_count(deleted_navmesh_count); + self.deleted_navmesh_count = deleted_navmesh_count; self } @@ -65,7 +65,8 @@ impl PluginCleaningData { mut self, detail: Vec, ) -> Result { - self.set_detail(detail)?; + validate_message_contents(&detail)?; + self.detail = detail.into_boxed_slice(); Ok(self) } @@ -79,34 +80,16 @@ impl PluginCleaningData { self.itm_count } - /// Set the number of Identical To Master records found in the plugin. - pub fn set_itm_count(&mut self, itm_count: u32) -> &mut Self { - self.itm_count = itm_count; - self - } - /// Get the number of deleted references found in the plugin. pub fn deleted_reference_count(&self) -> u32 { self.deleted_reference_count } - /// Set the number of deleted references found in the plugin. - pub fn set_deleted_reference_count(&mut self, deleted_reference_count: u32) -> &mut Self { - self.deleted_reference_count = deleted_reference_count; - self - } - /// Get the number of deleted navmeshes found in the plugin. pub fn deleted_navmesh_count(&self) -> u32 { self.deleted_navmesh_count } - /// Set the number of deleted navmeshes found in the plugin. - pub fn set_deleted_navmesh_count(&mut self, deleted_navmesh_count: u32) -> &mut Self { - self.deleted_navmesh_count = deleted_navmesh_count; - self - } - /// Get the cleaning utility that was used to check the plugin. /// /// The string may include a cleaning utility name, possibly related @@ -122,18 +105,6 @@ impl PluginCleaningData { pub fn detail(&self) -> &[MessageContent] { &self.detail } - - /// Set the detail message content, which may be appended to any messages - /// generated for this cleaning data. If multilingual, one language must be - /// [MessageContent::DEFAULT_LANGUAGE]. - pub fn set_detail( - &mut self, - detail: Vec, - ) -> Result<&mut Self, MultilingualMessageContentsError> { - validate_message_contents(&detail)?; - self.detail = detail.into_boxed_slice(); - Ok(self) - } } impl TryFromYaml for PluginCleaningData { diff --git a/src/metadata/tag.rs b/src/metadata/tag.rs index be2b7e72..08edd9e5 100644 --- a/src/metadata/tag.rs +++ b/src/metadata/tag.rs @@ -38,7 +38,7 @@ impl Tag { /// Set the condition string. #[must_use] pub fn with_condition(mut self, condition: String) -> Self { - self.set_condition(condition); + self.condition = Some(condition.into_boxed_str()); self } @@ -56,12 +56,6 @@ impl Tag { pub fn condition(&self) -> Option<&str> { self.condition.as_deref() } - - /// Set the condition string. - pub fn set_condition(&mut self, condition: String) -> &mut Self { - self.condition = Some(condition.into_boxed_str()); - self - } } impl TryFromYaml for Tag {