mirror of
https://github.com/loot/libloot.git
synced 2026-07-27 14:16:01 -07:00
Deny various rustc and clippy lints in ffi-errors crate
This commit is contained in:
@@ -47,6 +47,7 @@ impl std::fmt::Display for VerboseError {
|
||||
SystemErrorCategory::Esplugin => "EspluginError",
|
||||
SystemErrorCategory::Libloadorder => "LibloadorderError",
|
||||
SystemErrorCategory::LootConditionInterpreter => "LciError",
|
||||
_ => "UnknownCategoryError",
|
||||
};
|
||||
write!(f, "{}: {}: {}", prefix, e.code(), e.message())
|
||||
}
|
||||
|
||||
@@ -44,6 +44,13 @@ pub static ESP_ERROR_UNRESOLVED_RECORD_IDS: c_int = 13;
|
||||
#[unsafe(no_mangle)]
|
||||
pub static ESP_ERROR_PLUGIN_METADATA_NOT_FOUND: c_int = 14;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub static ESP_ERROR_UNKNOWN: c_int = c_int::MAX;
|
||||
|
||||
#[expect(
|
||||
clippy::wildcard_enum_match_arm,
|
||||
reason = "It doesn't matter if other I/O error kinds are added in the future"
|
||||
)]
|
||||
fn map_io_error(err: &std::io::Error) -> c_int {
|
||||
match err.kind() {
|
||||
std::io::ErrorKind::NotFound => ESP_ERROR_FILE_NOT_FOUND,
|
||||
@@ -52,12 +59,12 @@ fn map_io_error(err: &std::io::Error) -> c_int {
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_error(err: &Error) -> c_int {
|
||||
match *err {
|
||||
Error::IoError(ref x) => map_io_error(x),
|
||||
match err {
|
||||
Error::IoError(x) => map_io_error(x),
|
||||
Error::NoFilename(_) => ESP_ERROR_NO_FILENAME,
|
||||
Error::ParsingIncomplete(_) => ESP_ERROR_PARSE_ERROR,
|
||||
Error::ParsingError(_, _) => ESP_ERROR_PARSE_ERROR,
|
||||
Error::ParsingIncomplete(_) | Error::ParsingError(_, _) => ESP_ERROR_PARSE_ERROR,
|
||||
Error::DecodeError(_) => ESP_ERROR_TEXT_DECODE_ERROR,
|
||||
Error::UnresolvedRecordIds(_) => ESP_ERROR_UNRESOLVED_RECORD_IDS,
|
||||
Error::PluginMetadataNotFound(_) => ESP_ERROR_PLUGIN_METADATA_NOT_FOUND,
|
||||
|
||||
@@ -33,11 +33,15 @@ pub static LCI_ERROR_TEXT_ENCODE_FAIL: c_int = -7;
|
||||
#[unsafe(no_mangle)]
|
||||
pub static LCI_ERROR_INTERNAL_LOGIC_ERROR: c_int = -8;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub static LCI_ERROR_UNKNOWN: c_int = c_int::MAX;
|
||||
|
||||
#[must_use]
|
||||
pub fn map_error(err: &Error) -> c_int {
|
||||
match err {
|
||||
Error::ParsingIncomplete(_) => LCI_ERROR_PARSING_ERROR,
|
||||
Error::UnconsumedInput(_) => LCI_ERROR_PARSING_ERROR,
|
||||
Error::ParsingError(_, _) => LCI_ERROR_PARSING_ERROR,
|
||||
Error::ParsingIncomplete(_) | Error::UnconsumedInput(_) | Error::ParsingError(_, _) => {
|
||||
LCI_ERROR_PARSING_ERROR
|
||||
}
|
||||
Error::PeParsingError(_, _) => LCI_ERROR_PE_PARSING_ERROR,
|
||||
Error::IoError(_, _) => LCI_ERROR_IO_ERROR,
|
||||
_ => LCI_ERROR_INTERNAL_LOGIC_ERROR,
|
||||
|
||||
+143
-23
@@ -1,8 +1,106 @@
|
||||
// Deny some rustc lints that are allow-by-default.
|
||||
#![deny(
|
||||
ambiguous_negative_literals,
|
||||
impl_trait_overcaptures,
|
||||
let_underscore_drop,
|
||||
missing_copy_implementations,
|
||||
missing_debug_implementations,
|
||||
non_ascii_idents,
|
||||
redundant_imports,
|
||||
redundant_lifetimes,
|
||||
trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
unit_bindings,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![deny(clippy::pedantic)]
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
// Selectively deny clippy restriction lints.
|
||||
#![deny(
|
||||
clippy::allow_attributes,
|
||||
clippy::as_conversions,
|
||||
clippy::as_underscore,
|
||||
clippy::assertions_on_result_states,
|
||||
clippy::big_endian_bytes,
|
||||
clippy::cfg_not_test,
|
||||
clippy::clone_on_ref_ptr,
|
||||
clippy::create_dir,
|
||||
clippy::dbg_macro,
|
||||
clippy::decimal_literal_representation,
|
||||
clippy::default_numeric_fallback,
|
||||
clippy::doc_include_without_cfg,
|
||||
clippy::empty_drop,
|
||||
clippy::error_impl_error,
|
||||
clippy::exit,
|
||||
clippy::exhaustive_enums,
|
||||
clippy::expect_used,
|
||||
clippy::filetype_is_file,
|
||||
clippy::float_cmp_const,
|
||||
clippy::fn_to_numeric_cast_any,
|
||||
clippy::get_unwrap,
|
||||
clippy::host_endian_bytes,
|
||||
clippy::if_then_some_else_none,
|
||||
clippy::indexing_slicing,
|
||||
clippy::infinite_loop,
|
||||
clippy::integer_division,
|
||||
clippy::integer_division_remainder_used,
|
||||
clippy::iter_over_hash_type,
|
||||
clippy::let_underscore_must_use,
|
||||
clippy::lossy_float_literal,
|
||||
clippy::map_err_ignore,
|
||||
clippy::map_with_unused_argument_over_ranges,
|
||||
clippy::mem_forget,
|
||||
clippy::missing_assert_message,
|
||||
clippy::missing_asserts_for_indexing,
|
||||
clippy::missing_asserts_for_indexing,
|
||||
clippy::mixed_read_write_in_expression,
|
||||
clippy::multiple_inherent_impl,
|
||||
clippy::multiple_unsafe_ops_per_block,
|
||||
clippy::mutex_atomic,
|
||||
clippy::mutex_integer,
|
||||
clippy::needless_raw_strings,
|
||||
clippy::non_ascii_literal,
|
||||
clippy::non_zero_suggestions,
|
||||
clippy::panic,
|
||||
clippy::panic_in_result_fn,
|
||||
clippy::partial_pub_fields,
|
||||
clippy::pathbuf_init_then_push,
|
||||
clippy::precedence_bits,
|
||||
clippy::print_stderr,
|
||||
clippy::print_stdout,
|
||||
clippy::rc_buffer,
|
||||
clippy::rc_mutex,
|
||||
clippy::redundant_type_annotations,
|
||||
clippy::ref_patterns,
|
||||
clippy::rest_pat_in_fully_bound_structs,
|
||||
clippy::str_to_string,
|
||||
clippy::string_lit_chars_any,
|
||||
clippy::string_slice,
|
||||
clippy::string_to_string,
|
||||
clippy::suspicious_xor_used_as_pow,
|
||||
clippy::tests_outside_test_module,
|
||||
clippy::todo,
|
||||
clippy::try_err,
|
||||
clippy::undocumented_unsafe_blocks,
|
||||
clippy::unimplemented,
|
||||
clippy::unnecessary_safety_comment,
|
||||
clippy::unneeded_field_pattern,
|
||||
clippy::unreachable,
|
||||
clippy::unused_result_ok,
|
||||
clippy::unwrap_in_result,
|
||||
clippy::unwrap_used,
|
||||
clippy::use_debug,
|
||||
clippy::verbose_file_reads,
|
||||
clippy::wildcard_enum_match_arm
|
||||
)]
|
||||
use std::{
|
||||
error::Error,
|
||||
ffi::{c_int, c_uchar},
|
||||
};
|
||||
|
||||
use esplugin::ESP_ERROR_UNKNOWN;
|
||||
use lci::LCI_ERROR_UNKNOWN;
|
||||
use libloadorder::LIBLO_ERROR_UNKNOWN;
|
||||
use libloot::error::{ConditionEvaluationError, LoadOrderError, PluginDataError};
|
||||
|
||||
pub mod esplugin;
|
||||
@@ -23,6 +121,7 @@ pub static LIBLOOT_SYSTEM_ERROR_CATEGORY_LCI: c_uchar = 3;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[repr(u8)]
|
||||
#[non_exhaustive]
|
||||
pub enum SystemErrorCategory {
|
||||
Esplugin = LIBLOOT_SYSTEM_ERROR_CATEGORY_ESPLUGIN,
|
||||
Libloadorder = LIBLOOT_SYSTEM_ERROR_CATEGORY_LIBLOADORDER,
|
||||
@@ -49,14 +148,17 @@ pub struct SystemError {
|
||||
}
|
||||
|
||||
impl SystemError {
|
||||
#[must_use]
|
||||
pub fn code(&self) -> c_int {
|
||||
self.code
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn category(&self) -> SystemErrorCategory {
|
||||
self.category
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn message(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
@@ -76,48 +178,66 @@ impl std::error::Error for SystemError {}
|
||||
|
||||
impl From<PluginDataError> for SystemError {
|
||||
fn from(value: PluginDataError) -> Self {
|
||||
let error = value
|
||||
let (code, message) = if let Some(error) = value
|
||||
.source()
|
||||
.expect("LoadOrderError has source")
|
||||
.downcast_ref::<::esplugin::Error>()
|
||||
.expect("LoadOrderError source is an esplugin::Error");
|
||||
let error_code = crate::esplugin::map_error(error);
|
||||
.and_then(|s| s.downcast_ref::<::esplugin::Error>())
|
||||
{
|
||||
let error_code = crate::esplugin::map_error(error);
|
||||
(error_code, error.to_string())
|
||||
} else {
|
||||
(
|
||||
ESP_ERROR_UNKNOWN,
|
||||
"Could not retrieve esplugin error message".to_owned(),
|
||||
)
|
||||
};
|
||||
SystemError {
|
||||
code: error_code,
|
||||
code,
|
||||
category: SystemErrorCategory::Esplugin,
|
||||
message: error.to_string(),
|
||||
message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LoadOrderError> for SystemError {
|
||||
fn from(value: LoadOrderError) -> Self {
|
||||
let error = value
|
||||
let (code, message) = if let Some(error) = value
|
||||
.source()
|
||||
.expect("LoadOrderError has source")
|
||||
.downcast_ref::<loadorder::Error>()
|
||||
.expect("LoadOrderError source is a loadorder::Error");
|
||||
let error_code = crate::libloadorder::map_error(error);
|
||||
.and_then(|s| s.downcast_ref::<::loadorder::Error>())
|
||||
{
|
||||
let error_code = crate::libloadorder::map_error(error);
|
||||
(error_code, error.to_string())
|
||||
} else {
|
||||
(
|
||||
LIBLO_ERROR_UNKNOWN,
|
||||
"Could not retrieve libloadorder error message".to_owned(),
|
||||
)
|
||||
};
|
||||
SystemError {
|
||||
code: error_code,
|
||||
code,
|
||||
category: SystemErrorCategory::Libloadorder,
|
||||
message: error.to_string(),
|
||||
message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ConditionEvaluationError> for SystemError {
|
||||
fn from(value: ConditionEvaluationError) -> Self {
|
||||
let error = value
|
||||
let (code, message) = if let Some(error) = value
|
||||
.source()
|
||||
.expect("ConditionEvaluationError has source")
|
||||
.downcast_ref::<loot_condition_interpreter::Error>()
|
||||
.expect("ConditionEvaluationError source is a loot_condition_interpreter::Error");
|
||||
let error_code = crate::lci::map_error(error);
|
||||
.and_then(|s| s.downcast_ref::<::loot_condition_interpreter::Error>())
|
||||
{
|
||||
let error_code = crate::lci::map_error(error);
|
||||
(error_code, error.to_string())
|
||||
} else {
|
||||
(
|
||||
LCI_ERROR_UNKNOWN,
|
||||
"Could not retrieve loot-condition-interpreter error message".to_owned(),
|
||||
)
|
||||
};
|
||||
SystemError {
|
||||
code: error_code,
|
||||
code,
|
||||
category: SystemErrorCategory::LootConditionInterpreter,
|
||||
message: error.to_string(),
|
||||
message,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -137,9 +257,9 @@ pub fn fmt_error_chain(
|
||||
mut error: &dyn std::error::Error,
|
||||
f: &mut std::fmt::Formatter<'_>,
|
||||
) -> std::fmt::Result {
|
||||
write!(f, "{}", error)?;
|
||||
write!(f, "{error}")?;
|
||||
while let Some(source) = error.source() {
|
||||
write!(f, ": {}", source)?;
|
||||
write!(f, ": {source}")?;
|
||||
error = source;
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use loadorder::Error;
|
||||
use std::ffi::c_int;
|
||||
use std::{ffi::c_int, io::ErrorKind};
|
||||
|
||||
/// There is a mismatch between the files used to keep track of load order.
|
||||
///
|
||||
@@ -70,49 +70,55 @@ pub static LIBLO_ERROR_SYSTEM_ERROR: c_int = 22;
|
||||
#[unsafe(no_mangle)]
|
||||
pub static LIBLO_ERROR_NO_PATH: c_int = 23;
|
||||
|
||||
/// Matches the value of the highest-numbered return code.
|
||||
/// Matches the value of the highest-numbered return code, aside from `LIBLO_ERROR_UNKNOWN`.
|
||||
///
|
||||
/// Provided in case clients wish to incorporate additional return codes in their implementation
|
||||
/// and desire some method of avoiding value conflicts.
|
||||
#[unsafe(no_mangle)]
|
||||
pub static LIBLO_RETURN_MAX: c_int = 23;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub static LIBLO_ERROR_UNKNOWN: c_int = c_int::MAX;
|
||||
|
||||
#[expect(
|
||||
clippy::wildcard_enum_match_arm,
|
||||
reason = "It doesn't matter if other I/O error kinds are added in the future"
|
||||
)]
|
||||
fn map_io_error(err: &std::io::Error) -> c_int {
|
||||
use std::io::ErrorKind::*;
|
||||
match err.kind() {
|
||||
NotFound => LIBLO_ERROR_FILE_NOT_FOUND,
|
||||
AlreadyExists => LIBLO_ERROR_FILE_RENAME_FAIL,
|
||||
PermissionDenied => LIBLO_ERROR_IO_PERMISSION_DENIED,
|
||||
ErrorKind::NotFound => LIBLO_ERROR_FILE_NOT_FOUND,
|
||||
ErrorKind::AlreadyExists => LIBLO_ERROR_FILE_RENAME_FAIL,
|
||||
ErrorKind::PermissionDenied => LIBLO_ERROR_IO_PERMISSION_DENIED,
|
||||
_ => LIBLO_ERROR_IO_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn map_error(err: &Error) -> c_int {
|
||||
use Error::*;
|
||||
match *err {
|
||||
InvalidPath(_) => LIBLO_ERROR_FILE_NOT_FOUND,
|
||||
IoError(_, ref x) => map_io_error(x),
|
||||
NoFilename(_) => LIBLO_ERROR_FILE_PARSE_FAIL,
|
||||
DecodeError(_) => LIBLO_ERROR_TEXT_DECODE_FAIL,
|
||||
EncodeError(_) => LIBLO_ERROR_TEXT_ENCODE_FAIL,
|
||||
PluginParsingError(_, _) => LIBLO_ERROR_FILE_PARSE_FAIL,
|
||||
PluginNotFound(_) => LIBLO_ERROR_INVALID_ARGS,
|
||||
TooManyActivePlugins { .. } => LIBLO_ERROR_INVALID_ARGS,
|
||||
DuplicatePlugin(_) => LIBLO_ERROR_INVALID_ARGS,
|
||||
NonMasterBeforeMaster { .. } => LIBLO_ERROR_INVALID_ARGS,
|
||||
InvalidEarlyLoadingPluginPosition { .. } => LIBLO_ERROR_INVALID_ARGS,
|
||||
ImplicitlyActivePlugin(_) => LIBLO_ERROR_INVALID_ARGS,
|
||||
NoLocalAppData => LIBLO_ERROR_INVALID_ARGS,
|
||||
NoDocumentsPath => LIBLO_ERROR_INVALID_ARGS,
|
||||
NoUserConfigPath => LIBLO_ERROR_NO_PATH,
|
||||
NoUserDataPath => LIBLO_ERROR_NO_PATH,
|
||||
NoProgramFilesPath => LIBLO_ERROR_NO_PATH,
|
||||
UnrepresentedHoist { .. } => LIBLO_ERROR_INVALID_ARGS,
|
||||
InstalledPlugin(_) => LIBLO_ERROR_INVALID_ARGS,
|
||||
IniParsingError { .. } => LIBLO_ERROR_FILE_PARSE_FAIL,
|
||||
VdfParsingError(_, _) => LIBLO_ERROR_FILE_PARSE_FAIL,
|
||||
SystemError(_, _) => LIBLO_ERROR_SYSTEM_ERROR,
|
||||
InvalidBlueprintPluginPosition { .. } => LIBLO_ERROR_INVALID_ARGS,
|
||||
match err {
|
||||
Error::InvalidPath(_) => LIBLO_ERROR_FILE_NOT_FOUND,
|
||||
Error::IoError(_, x) => map_io_error(x),
|
||||
Error::NoFilename(_)
|
||||
| Error::PluginParsingError(_, _)
|
||||
| Error::IniParsingError { .. }
|
||||
| Error::VdfParsingError(_, _) => LIBLO_ERROR_FILE_PARSE_FAIL,
|
||||
Error::DecodeError(_) => LIBLO_ERROR_TEXT_DECODE_FAIL,
|
||||
Error::EncodeError(_) => LIBLO_ERROR_TEXT_ENCODE_FAIL,
|
||||
Error::PluginNotFound(_)
|
||||
| Error::TooManyActivePlugins { .. }
|
||||
| Error::DuplicatePlugin(_)
|
||||
| Error::NonMasterBeforeMaster { .. }
|
||||
| Error::InvalidEarlyLoadingPluginPosition { .. }
|
||||
| Error::ImplicitlyActivePlugin(_)
|
||||
| Error::NoLocalAppData
|
||||
| Error::NoDocumentsPath
|
||||
| Error::UnrepresentedHoist { .. }
|
||||
| Error::InstalledPlugin(_)
|
||||
| Error::InvalidBlueprintPluginPosition { .. } => LIBLO_ERROR_INVALID_ARGS,
|
||||
Error::NoUserConfigPath | Error::NoUserDataPath | Error::NoProgramFilesPath => {
|
||||
LIBLO_ERROR_NO_PATH
|
||||
}
|
||||
Error::SystemError(_, _) => LIBLO_ERROR_SYSTEM_ERROR,
|
||||
_ => LIBLO_ERROR_INTERNAL_LOGIC_ERROR,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user