mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Replace WriteMode with MetadataWriteOptions
This is a breaking API change, but the addition of any future options won't be.
This commit is contained in:
@@ -4,7 +4,75 @@
|
||||
#include "api/convert.h"
|
||||
#include "api/exception/exception.h"
|
||||
|
||||
namespace {
|
||||
loot::MetadataWriteOptionsImpl convert(
|
||||
const loot::MetadataWriteOptions& options) {
|
||||
loot::MetadataWriteOptionsImpl output;
|
||||
|
||||
output.truncate = options.GetTruncate();
|
||||
output.write_anchors = options.GetWriteAnchors();
|
||||
output.write_common_section = options.GetWriteCommonSection();
|
||||
output.anchor_file_strings = options.GetAnchorFileStrings();
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
namespace loot {
|
||||
MetadataWriteOptions::MetadataWriteOptions() :
|
||||
pimpl_(std::make_unique<MetadataWriteOptionsImpl>()) {}
|
||||
|
||||
MetadataWriteOptions::MetadataWriteOptions(const MetadataWriteOptions& other) :
|
||||
pimpl_(std::make_unique<MetadataWriteOptionsImpl>(*other.pimpl_)) {}
|
||||
|
||||
MetadataWriteOptions::MetadataWriteOptions(
|
||||
MetadataWriteOptions&& other) noexcept :
|
||||
pimpl_(std::move(other).pimpl_) {}
|
||||
|
||||
MetadataWriteOptions::~MetadataWriteOptions() {}
|
||||
|
||||
MetadataWriteOptions& MetadataWriteOptions::operator=(
|
||||
const MetadataWriteOptions& other) {
|
||||
*pimpl_ = *other.pimpl_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MetadataWriteOptions& MetadataWriteOptions::operator=(
|
||||
MetadataWriteOptions&& other) noexcept {
|
||||
pimpl_ = std::move(other.pimpl_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void MetadataWriteOptions::SetTruncate(bool truncate) {
|
||||
pimpl_->truncate = truncate;
|
||||
}
|
||||
|
||||
void MetadataWriteOptions::SetWriteAnchors(bool writeAnchors) {
|
||||
pimpl_->write_anchors = writeAnchors;
|
||||
}
|
||||
|
||||
void MetadataWriteOptions::SetWriteCommonSection(bool writeCommonSection) {
|
||||
pimpl_->write_common_section = writeCommonSection;
|
||||
}
|
||||
|
||||
void MetadataWriteOptions::SetAnchorFileStrings(bool anchorFileStrings) {
|
||||
pimpl_->anchor_file_strings = anchorFileStrings;
|
||||
}
|
||||
|
||||
bool MetadataWriteOptions::GetTruncate() const { return pimpl_->truncate; }
|
||||
|
||||
bool MetadataWriteOptions::GetWriteAnchors() const {
|
||||
return pimpl_->write_anchors;
|
||||
}
|
||||
|
||||
bool MetadataWriteOptions::GetWriteCommonSection() const {
|
||||
return pimpl_->write_common_section;
|
||||
}
|
||||
|
||||
bool MetadataWriteOptions::GetAnchorFileStrings() const {
|
||||
return pimpl_->anchor_file_strings;
|
||||
}
|
||||
|
||||
Database::Database(::rust::Box<loot::rust::Database>&& database) :
|
||||
database_(std::move(database)) {}
|
||||
|
||||
@@ -36,9 +104,9 @@ void Database::LoadUserlist(const std::filesystem::path& userlistPath) {
|
||||
}
|
||||
|
||||
void Database::WriteUserMetadata(const std::filesystem::path& outputFile,
|
||||
const bool overwrite) const {
|
||||
const MetadataWriteOptions& options) const {
|
||||
try {
|
||||
database_->write_user_metadata(outputFile.u8string(), overwrite);
|
||||
database_->write_user_metadata(outputFile.u8string(), ::convert(options));
|
||||
} catch (const ::rust::Error& e) {
|
||||
std::rethrow_exception(mapError(e));
|
||||
}
|
||||
@@ -209,9 +277,9 @@ void Database::DiscardAllUserMetadata() {
|
||||
}
|
||||
|
||||
void Database::WriteMinimalList(const std::filesystem::path& outputFile,
|
||||
const bool overwrite) const {
|
||||
const MetadataWriteOptions& options) const {
|
||||
try {
|
||||
database_->write_minimal_list(outputFile.u8string(), overwrite);
|
||||
database_->write_minimal_list(outputFile.u8string(), ::convert(options));
|
||||
} catch (const ::rust::Error& e) {
|
||||
std::rethrow_exception(mapError(e));
|
||||
}
|
||||
|
||||
@@ -10,19 +10,19 @@ class Database final : public DatabaseInterface {
|
||||
public:
|
||||
explicit Database(::rust::Box<loot::rust::Database>&& database);
|
||||
|
||||
void LoadMasterlist(const std::filesystem::path& masterlist_path) override;
|
||||
void LoadMasterlist(const std::filesystem::path& masterlistPath) override;
|
||||
|
||||
void LoadMasterlistWithPrelude(
|
||||
const std::filesystem::path& masterlist_path,
|
||||
const std::filesystem::path& masterlist_prelude_path) override;
|
||||
const std::filesystem::path& masterlistPath,
|
||||
const std::filesystem::path& masterlistPreludePath) override;
|
||||
|
||||
void LoadUserlist(const std::filesystem::path& userlist_path) override;
|
||||
|
||||
void WriteUserMetadata(const std::filesystem::path& outputFile,
|
||||
const bool overwrite) const override;
|
||||
const MetadataWriteOptions& options) const override;
|
||||
|
||||
void WriteMinimalList(const std::filesystem::path& outputFile,
|
||||
const bool overwrite) const override;
|
||||
const MetadataWriteOptions& options) const override;
|
||||
|
||||
bool Evaluate(const std::string& condition) const override;
|
||||
|
||||
|
||||
+6
-18
@@ -4,12 +4,12 @@ use std::{
|
||||
};
|
||||
|
||||
use delegate::delegate;
|
||||
use libloot::{EvalMode, MergeMode, WriteMode, error::DatabaseLockPoisonError};
|
||||
use libloot::{EvalMode, MergeMode, error::DatabaseLockPoisonError};
|
||||
use libloot_ffi_errors::UnsupportedEnumValueError;
|
||||
|
||||
use crate::{
|
||||
OptionalPluginMetadata, VerboseError,
|
||||
ffi::EdgeType,
|
||||
ffi::{EdgeType, MetadataWriteOptionsImpl},
|
||||
metadata::{Group, Message, PluginMetadata, to_vec_of_unwrapped},
|
||||
};
|
||||
|
||||
@@ -53,36 +53,24 @@ impl Database {
|
||||
pub fn write_user_metadata(
|
||||
&self,
|
||||
output_path: &str,
|
||||
overwrite: bool,
|
||||
options: MetadataWriteOptionsImpl,
|
||||
) -> Result<(), VerboseError> {
|
||||
let write_mode = if overwrite {
|
||||
WriteMode::CreateOrTruncate
|
||||
} else {
|
||||
WriteMode::Create
|
||||
};
|
||||
|
||||
self.0
|
||||
.read()
|
||||
.map_err(DatabaseLockPoisonError::from)?
|
||||
.write_user_metadata(Path::new(output_path), write_mode)
|
||||
.write_user_metadata(Path::new(output_path), &options.into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn write_minimal_list(
|
||||
&self,
|
||||
output_path: &str,
|
||||
overwrite: bool,
|
||||
options: MetadataWriteOptionsImpl,
|
||||
) -> Result<(), VerboseError> {
|
||||
let write_mode = if overwrite {
|
||||
WriteMode::CreateOrTruncate
|
||||
} else {
|
||||
WriteMode::Create
|
||||
};
|
||||
|
||||
self.0
|
||||
.read()
|
||||
.map_err(DatabaseLockPoisonError::from)?
|
||||
.write_minimal_list(Path::new(output_path), write_mode)
|
||||
.write_minimal_list(Path::new(output_path), &options.into())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
|
||||
+32
-4
@@ -17,7 +17,7 @@ mod plugin;
|
||||
|
||||
use database::{Database, Vertex, new_vertex};
|
||||
use error::{EmptyOptionalError, VerboseError};
|
||||
use ffi::OptionalMessageContentRef;
|
||||
use ffi::{MetadataWriteOptionsImpl, OptionalMessageContentRef};
|
||||
use game::{Game, new_game, new_game_with_local_path};
|
||||
use libloot_ffi_errors::UnsupportedEnumValueError;
|
||||
use metadata::{
|
||||
@@ -112,6 +112,18 @@ impl TryFrom<ffi::LogLevel> for libloot::LogLevel {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<MetadataWriteOptionsImpl> for libloot::MetadataWriteOptions {
|
||||
fn from(value: MetadataWriteOptionsImpl) -> Self {
|
||||
let mut options = libloot::MetadataWriteOptions::new();
|
||||
options.set_truncate(value.truncate);
|
||||
options.set_write_anchors(value.write_anchors);
|
||||
options.set_write_common_section(value.write_common_section);
|
||||
options.set_anchor_file_strings(value.anchor_file_strings);
|
||||
|
||||
options
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(
|
||||
let_underscore_drop,
|
||||
missing_debug_implementations,
|
||||
@@ -123,7 +135,6 @@ impl TryFrom<ffi::LogLevel> for libloot::LogLevel {
|
||||
)]
|
||||
#[cxx::bridge(namespace = "loot::rust")]
|
||||
mod ffi {
|
||||
|
||||
pub enum GameType {
|
||||
Oblivion,
|
||||
Skyrim,
|
||||
@@ -181,6 +192,15 @@ mod ffi {
|
||||
pointer: *const MessageContent,
|
||||
}
|
||||
|
||||
#[namespace = "loot"]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct MetadataWriteOptionsImpl {
|
||||
truncate: bool,
|
||||
write_anchors: bool,
|
||||
write_common_section: bool,
|
||||
anchor_file_strings: bool,
|
||||
}
|
||||
|
||||
extern "Rust" {
|
||||
pub fn is_some(self: &OptionalMessageContentRef) -> bool;
|
||||
|
||||
@@ -260,9 +280,17 @@ mod ffi {
|
||||
|
||||
pub fn load_userlist(&self, path: &str) -> Result<()>;
|
||||
|
||||
pub fn write_user_metadata(&self, output_path: &str, overwrite: bool) -> Result<()>;
|
||||
pub fn write_user_metadata(
|
||||
&self,
|
||||
output_path: &str,
|
||||
options: MetadataWriteOptionsImpl,
|
||||
) -> Result<()>;
|
||||
|
||||
pub fn write_minimal_list(&self, output_path: &str, overwrite: bool) -> Result<()>;
|
||||
pub fn write_minimal_list(
|
||||
&self,
|
||||
output_path: &str,
|
||||
options: MetadataWriteOptionsImpl,
|
||||
) -> Result<()>;
|
||||
|
||||
pub fn evaluate(&self, condition: &str) -> Result<bool>;
|
||||
|
||||
|
||||
@@ -198,46 +198,55 @@ TEST_P(DatabaseInterfaceTest, loadUserlistShouldSucceedIfTheUserlistIsPresent) {
|
||||
TEST_P(
|
||||
DatabaseInterfaceTest,
|
||||
writeUserMetadataShouldThrowIfTheFileAlreadyExistsAndTheOverwriteArgumentIsFalse) {
|
||||
ASSERT_NO_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, false));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().WriteUserMetadata(
|
||||
minimalOutputPath_, MetadataWriteOptions()));
|
||||
ASSERT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
EXPECT_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, false),
|
||||
std::runtime_error);
|
||||
EXPECT_THROW(handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_,
|
||||
MetadataWriteOptions()),
|
||||
std::runtime_error);
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
DatabaseInterfaceTest,
|
||||
writeUserMetadataShouldReturnOkAndWriteToFileIfTheArgumentsAreValidAndTheOverwriteArgumentIsTrue) {
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, true));
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, options));
|
||||
EXPECT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
DatabaseInterfaceTest,
|
||||
writeUserMetadataShouldReturnOkIfTheFileAlreadyExistsAndTheOverwriteArgumentIsTrue) {
|
||||
ASSERT_NO_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, false));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().WriteUserMetadata(
|
||||
minimalOutputPath_, MetadataWriteOptions()));
|
||||
ASSERT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, true));
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, options));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
writeUserMetadataShouldThrowIfPathGivenExistsAndIsReadOnly) {
|
||||
ASSERT_NO_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, false));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().WriteUserMetadata(
|
||||
minimalOutputPath_, MetadataWriteOptions()));
|
||||
ASSERT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
std::filesystem::permissions(minimalOutputPath_,
|
||||
std::filesystem::perms::owner_read,
|
||||
std::filesystem::perm_options::replace);
|
||||
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, true),
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, options),
|
||||
std::runtime_error);
|
||||
}
|
||||
|
||||
@@ -246,8 +255,11 @@ TEST_P(DatabaseInterfaceTest,
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath));
|
||||
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, true));
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, options));
|
||||
|
||||
EXPECT_EQ("{}", GetFileContent(minimalOutputPath_));
|
||||
}
|
||||
@@ -263,8 +275,11 @@ TEST_P(DatabaseInterfaceTest, writeUserMetadataShouldShouldWriteUserMetadata) {
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().LoadUserlist(userlistPath_));
|
||||
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, true));
|
||||
handle_->GetDatabase().WriteUserMetadata(minimalOutputPath_, options));
|
||||
|
||||
EXPECT_FALSE(GetFileContent(minimalOutputPath_).empty());
|
||||
}
|
||||
@@ -899,54 +914,63 @@ TEST_P(
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
writeMinimalListShouldReturnOkAndWriteToFileIfArgumentsGivenAreValid) {
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, false));
|
||||
EXPECT_NO_THROW(handle_->GetDatabase().WriteMinimalList(
|
||||
minimalOutputPath_, MetadataWriteOptions()));
|
||||
EXPECT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
DatabaseInterfaceTest,
|
||||
writeMinimalListShouldThrowIfTheFileAlreadyExistsAndTheOverwriteArgumentIsFalse) {
|
||||
ASSERT_NO_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, false));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().WriteMinimalList(
|
||||
minimalOutputPath_, MetadataWriteOptions()));
|
||||
ASSERT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
EXPECT_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, false),
|
||||
std::runtime_error);
|
||||
EXPECT_THROW(handle_->GetDatabase().WriteMinimalList(minimalOutputPath_,
|
||||
MetadataWriteOptions()),
|
||||
std::runtime_error);
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
DatabaseInterfaceTest,
|
||||
writeMinimalListShouldReturnOkAndWriteToFileIfTheArgumentsAreValidAndTheOverwriteArgumentIsTrue) {
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, true));
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, options));
|
||||
EXPECT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
DatabaseInterfaceTest,
|
||||
writeMinimalListShouldReturnOkIfTheFileAlreadyExistsAndTheOverwriteArgumentIsTrue) {
|
||||
ASSERT_NO_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, false));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().WriteMinimalList(
|
||||
minimalOutputPath_, MetadataWriteOptions()));
|
||||
ASSERT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, true));
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, options));
|
||||
}
|
||||
|
||||
TEST_P(DatabaseInterfaceTest,
|
||||
writeMinimalListShouldThrowIfPathGivenExistsAndIsReadOnly) {
|
||||
ASSERT_NO_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, false));
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().WriteMinimalList(
|
||||
minimalOutputPath_, MetadataWriteOptions()));
|
||||
ASSERT_TRUE(std::filesystem::exists(minimalOutputPath_));
|
||||
|
||||
std::filesystem::permissions(minimalOutputPath_,
|
||||
std::filesystem::perms::owner_read,
|
||||
std::filesystem::perm_options::replace);
|
||||
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, true),
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, options),
|
||||
std::runtime_error);
|
||||
}
|
||||
|
||||
@@ -957,8 +981,11 @@ TEST_P(DatabaseInterfaceTest,
|
||||
ASSERT_NO_THROW(GenerateMasterlist());
|
||||
ASSERT_NO_THROW(handle_->GetDatabase().LoadMasterlist(masterlistPath));
|
||||
|
||||
MetadataWriteOptions options;
|
||||
options.SetTruncate(true);
|
||||
|
||||
EXPECT_NO_THROW(
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, true));
|
||||
handle_->GetDatabase().WriteMinimalList(minimalOutputPath_, options));
|
||||
|
||||
const auto content = GetFileContent(minimalOutputPath_);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user