pub trait ConfigEnum: Sized {
    fn variants() -> &'static [Self];
    fn variant_info() -> &'static [ConfigEnumVariantInfo];
    fn as_str(&self) -> &'static str;
    fn name(&self) -> &'static str;
    fn description(&self) -> Option<&'static str>;
}
#[derive(Clone, Debug)]
pub struct ConfigEnumVariantInfo {
    pub value: &'static str,
    pub name: &'static str,
    pub description: Option<&'static str>,
    pub is_default: bool,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum ConfigPropertyId {
    /// Function relocation diffs
    ///
    /// How relocation targets will be diffed in the function view.
    FunctionRelocDiffs,
    /// Demangler
    ///
    /// Which demangler should be used to demangle each symbol.
    Demangler,
    /// (Experimental) Perform data flow analysis
    ///
    /// Use data flow analysis to display known information about register contents where possible
    AnalyzeDataFlow,
    /// Show data flow
    ///
    /// Show data flow analysis results in place of register name where present
    ShowDataFlow,
    /// Space between args
    ///
    /// Adds a space between arguments in the diff output.
    SpaceBetweenArgs,
    /// Show symbol sizes
    ///
    /// Shows symbol sizes in the symbol view.
    ShowSymbolSizes,
    /// Combine data sections
    ///
    /// Combines data sections with equal names.
    CombineDataSections,
    /// Combine text sections
    ///
    /// Combines all text sections into one.
    CombineTextSections,
    /// Preferred string encoding
    ///
    /// Which encoding to use when diffing string literals used in functions.
    PreferredStringEncoding,
    /// Architecture version
    ///
    /// ARM architecture version to use for disassembly.
    ArmArchVersion,
    /// VFPv2 instructions
    ///
    /// Adds floating-point instructions from VFPv2.
    ArmVfpV2,
    /// Unified syntax
    ///
    /// Disassemble as unified assembly language (UAL).
    ArmUnifiedSyntax,
    /// Use A/V registers
    ///
    /// Display R0-R3 as A1-A4 and R4-R11 as V1-V8.
    ArmAvRegisters,
    /// Display R9 as
    ArmR9Usage,
    /// Display R10 as SL
    ///
    /// Used for explicit stack limits.
    ArmSlUsage,
    /// Display R11 as FP
    ///
    /// Used for frame pointers.
    ArmFpUsage,
    /// Display R12 as IP
    ///
    /// Used for interworking and long branches.
    ArmIpUsage,
    /// ABI
    ///
    /// MIPS ABI to use for disassembly.
    MipsAbi,
    /// Instruction category
    ///
    /// MIPS instruction category to use for disassembly.
    MipsInstrCategory,
    /// Register '$' prefix
    ///
    /// Display MIPS register names with a '$' prefix.
    MipsRegisterPrefix,
    /// ProDG SN AS VU register order
    ///
    /// Changes the register order for specific R5900EE instructions to match the syntax used by the SN AS from ProDG (-snas flag).
    MipsProdgSnAsInvertedRegs,
    /// Calculate pooled data references
    ///
    /// Display pooled data references in functions as fake relocations.
    PpcCalculatePoolRelocations,
    /// Format
    ///
    /// x86 disassembly syntax.
    X86Formatter,
}
impl ConfigEnum for ConfigPropertyId {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[ConfigPropertyId] = &[
            ConfigPropertyId::FunctionRelocDiffs,
            ConfigPropertyId::Demangler,
            ConfigPropertyId::AnalyzeDataFlow,
            ConfigPropertyId::ShowDataFlow,
            ConfigPropertyId::SpaceBetweenArgs,
            ConfigPropertyId::ShowSymbolSizes,
            ConfigPropertyId::CombineDataSections,
            ConfigPropertyId::CombineTextSections,
            ConfigPropertyId::PreferredStringEncoding,
            ConfigPropertyId::ArmArchVersion,
            ConfigPropertyId::ArmVfpV2,
            ConfigPropertyId::ArmUnifiedSyntax,
            ConfigPropertyId::ArmAvRegisters,
            ConfigPropertyId::ArmR9Usage,
            ConfigPropertyId::ArmSlUsage,
            ConfigPropertyId::ArmFpUsage,
            ConfigPropertyId::ArmIpUsage,
            ConfigPropertyId::MipsAbi,
            ConfigPropertyId::MipsInstrCategory,
            ConfigPropertyId::MipsRegisterPrefix,
            ConfigPropertyId::MipsProdgSnAsInvertedRegs,
            ConfigPropertyId::PpcCalculatePoolRelocations,
            ConfigPropertyId::X86Formatter,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "functionRelocDiffs",
                name: "Function relocation diffs",
                description: Some(
                    "How relocation targets will be diffed in the function view.",
                ),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "demangler",
                name: "Demangler",
                description: Some(
                    "Which demangler should be used to demangle each symbol.",
                ),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "analyzeDataFlow",
                name: "(Experimental) Perform data flow analysis",
                description: Some(
                    "Use data flow analysis to display known information about register contents where possible",
                ),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "showDataFlow",
                name: "Show data flow",
                description: Some(
                    "Show data flow analysis results in place of register name where present",
                ),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "spaceBetweenArgs",
                name: "Space between args",
                description: Some("Adds a space between arguments in the diff output."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "showSymbolSizes",
                name: "Show symbol sizes",
                description: Some("Shows symbol sizes in the symbol view."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "combineDataSections",
                name: "Combine data sections",
                description: Some("Combines data sections with equal names."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "combineTextSections",
                name: "Combine text sections",
                description: Some("Combines all text sections into one."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "preferredStringEncoding",
                name: "Preferred string encoding",
                description: Some(
                    "Which encoding to use when diffing string literals used in functions.",
                ),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.archVersion",
                name: "Architecture version",
                description: Some("ARM architecture version to use for disassembly."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.vfpV2",
                name: "VFPv2 instructions",
                description: Some("Adds floating-point instructions from VFPv2."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.unifiedSyntax",
                name: "Unified syntax",
                description: Some("Disassemble as unified assembly language (UAL)."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.avRegisters",
                name: "Use A/V registers",
                description: Some("Display R0-R3 as A1-A4 and R4-R11 as V1-V8."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.r9Usage",
                name: "Display R9 as",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.slUsage",
                name: "Display R10 as SL",
                description: Some("Used for explicit stack limits."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.fpUsage",
                name: "Display R11 as FP",
                description: Some("Used for frame pointers."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "arm.ipUsage",
                name: "Display R12 as IP",
                description: Some("Used for interworking and long branches."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "mips.abi",
                name: "ABI",
                description: Some("MIPS ABI to use for disassembly."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "mips.instrCategory",
                name: "Instruction category",
                description: Some("MIPS instruction category to use for disassembly."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "mips.registerPrefix",
                name: "Register '$' prefix",
                description: Some("Display MIPS register names with a '$' prefix."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "mips.prodgSnAsInvertedRegs",
                name: "ProDG SN AS VU register order",
                description: Some(
                    "Changes the register order for specific R5900EE instructions to match the syntax used by the SN AS from ProDG (-snas flag).",
                ),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "ppc.calculatePoolRelocations",
                name: "Calculate pooled data references",
                description: Some(
                    "Display pooled data references in functions as fake relocations.",
                ),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "x86.formatter",
                name: "Format",
                description: Some("x86 disassembly syntax."),
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            Self::FunctionRelocDiffs => "functionRelocDiffs",
            Self::Demangler => "demangler",
            Self::AnalyzeDataFlow => "analyzeDataFlow",
            Self::ShowDataFlow => "showDataFlow",
            Self::SpaceBetweenArgs => "spaceBetweenArgs",
            Self::ShowSymbolSizes => "showSymbolSizes",
            Self::CombineDataSections => "combineDataSections",
            Self::CombineTextSections => "combineTextSections",
            Self::PreferredStringEncoding => "preferredStringEncoding",
            Self::ArmArchVersion => "arm.archVersion",
            Self::ArmVfpV2 => "arm.vfpV2",
            Self::ArmUnifiedSyntax => "arm.unifiedSyntax",
            Self::ArmAvRegisters => "arm.avRegisters",
            Self::ArmR9Usage => "arm.r9Usage",
            Self::ArmSlUsage => "arm.slUsage",
            Self::ArmFpUsage => "arm.fpUsage",
            Self::ArmIpUsage => "arm.ipUsage",
            Self::MipsAbi => "mips.abi",
            Self::MipsInstrCategory => "mips.instrCategory",
            Self::MipsRegisterPrefix => "mips.registerPrefix",
            Self::MipsProdgSnAsInvertedRegs => "mips.prodgSnAsInvertedRegs",
            Self::PpcCalculatePoolRelocations => "ppc.calculatePoolRelocations",
            Self::X86Formatter => "x86.formatter",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            Self::FunctionRelocDiffs => "Function relocation diffs",
            Self::Demangler => "Demangler",
            Self::AnalyzeDataFlow => "(Experimental) Perform data flow analysis",
            Self::ShowDataFlow => "Show data flow",
            Self::SpaceBetweenArgs => "Space between args",
            Self::ShowSymbolSizes => "Show symbol sizes",
            Self::CombineDataSections => "Combine data sections",
            Self::CombineTextSections => "Combine text sections",
            Self::PreferredStringEncoding => "Preferred string encoding",
            Self::ArmArchVersion => "Architecture version",
            Self::ArmVfpV2 => "VFPv2 instructions",
            Self::ArmUnifiedSyntax => "Unified syntax",
            Self::ArmAvRegisters => "Use A/V registers",
            Self::ArmR9Usage => "Display R9 as",
            Self::ArmSlUsage => "Display R10 as SL",
            Self::ArmFpUsage => "Display R11 as FP",
            Self::ArmIpUsage => "Display R12 as IP",
            Self::MipsAbi => "ABI",
            Self::MipsInstrCategory => "Instruction category",
            Self::MipsRegisterPrefix => "Register '$' prefix",
            Self::MipsProdgSnAsInvertedRegs => "ProDG SN AS VU register order",
            Self::PpcCalculatePoolRelocations => "Calculate pooled data references",
            Self::X86Formatter => "Format",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            Self::FunctionRelocDiffs => {
                Some("How relocation targets will be diffed in the function view.")
            }
            Self::Demangler => {
                Some("Which demangler should be used to demangle each symbol.")
            }
            Self::AnalyzeDataFlow => {
                Some(
                    "Use data flow analysis to display known information about register contents where possible",
                )
            }
            Self::ShowDataFlow => {
                Some(
                    "Show data flow analysis results in place of register name where present",
                )
            }
            Self::SpaceBetweenArgs => {
                Some("Adds a space between arguments in the diff output.")
            }
            Self::ShowSymbolSizes => Some("Shows symbol sizes in the symbol view."),
            Self::CombineDataSections => Some("Combines data sections with equal names."),
            Self::CombineTextSections => Some("Combines all text sections into one."),
            Self::PreferredStringEncoding => {
                Some(
                    "Which encoding to use when diffing string literals used in functions.",
                )
            }
            Self::ArmArchVersion => {
                Some("ARM architecture version to use for disassembly.")
            }
            Self::ArmVfpV2 => Some("Adds floating-point instructions from VFPv2."),
            Self::ArmUnifiedSyntax => {
                Some("Disassemble as unified assembly language (UAL).")
            }
            Self::ArmAvRegisters => Some("Display R0-R3 as A1-A4 and R4-R11 as V1-V8."),
            Self::ArmR9Usage => None,
            Self::ArmSlUsage => Some("Used for explicit stack limits."),
            Self::ArmFpUsage => Some("Used for frame pointers."),
            Self::ArmIpUsage => Some("Used for interworking and long branches."),
            Self::MipsAbi => Some("MIPS ABI to use for disassembly."),
            Self::MipsInstrCategory => {
                Some("MIPS instruction category to use for disassembly.")
            }
            Self::MipsRegisterPrefix => {
                Some("Display MIPS register names with a '$' prefix.")
            }
            Self::MipsProdgSnAsInvertedRegs => {
                Some(
                    "Changes the register order for specific R5900EE instructions to match the syntax used by the SN AS from ProDG (-snas flag).",
                )
            }
            Self::PpcCalculatePoolRelocations => {
                Some("Display pooled data references in functions as fake relocations.")
            }
            Self::X86Formatter => Some("x86 disassembly syntax."),
        }
    }
}
impl ConfigPropertyId {
    pub fn kind(&self) -> ConfigPropertyKind {
        match self {
            Self::FunctionRelocDiffs => {
                ConfigPropertyKind::Choice(FunctionRelocDiffs::variant_info())
            }
            Self::Demangler => ConfigPropertyKind::Choice(Demangler::variant_info()),
            Self::AnalyzeDataFlow => ConfigPropertyKind::Boolean,
            Self::ShowDataFlow => ConfigPropertyKind::Boolean,
            Self::SpaceBetweenArgs => ConfigPropertyKind::Boolean,
            Self::ShowSymbolSizes => {
                ConfigPropertyKind::Choice(ShowSymbolSizes::variant_info())
            }
            Self::CombineDataSections => ConfigPropertyKind::Boolean,
            Self::CombineTextSections => ConfigPropertyKind::Boolean,
            Self::PreferredStringEncoding => {
                ConfigPropertyKind::Choice(PreferredStringEncoding::variant_info())
            }
            Self::ArmArchVersion => {
                ConfigPropertyKind::Choice(ArmArchVersion::variant_info())
            }
            Self::ArmVfpV2 => ConfigPropertyKind::Boolean,
            Self::ArmUnifiedSyntax => ConfigPropertyKind::Boolean,
            Self::ArmAvRegisters => ConfigPropertyKind::Boolean,
            Self::ArmR9Usage => ConfigPropertyKind::Choice(ArmR9Usage::variant_info()),
            Self::ArmSlUsage => ConfigPropertyKind::Boolean,
            Self::ArmFpUsage => ConfigPropertyKind::Boolean,
            Self::ArmIpUsage => ConfigPropertyKind::Boolean,
            Self::MipsAbi => ConfigPropertyKind::Choice(MipsAbi::variant_info()),
            Self::MipsInstrCategory => {
                ConfigPropertyKind::Choice(MipsInstrCategory::variant_info())
            }
            Self::MipsRegisterPrefix => ConfigPropertyKind::Boolean,
            Self::MipsProdgSnAsInvertedRegs => ConfigPropertyKind::Boolean,
            Self::PpcCalculatePoolRelocations => ConfigPropertyKind::Boolean,
            Self::X86Formatter => {
                ConfigPropertyKind::Choice(X86Formatter::variant_info())
            }
        }
    }
}
impl core::str::FromStr for ConfigPropertyId {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("functionRelocDiffs")
            || s.eq_ignore_ascii_case("function_reloc_diffs")
        {
            return Ok(Self::FunctionRelocDiffs);
        }
        if s.eq_ignore_ascii_case("demangler") || s.eq_ignore_ascii_case("demangler") {
            return Ok(Self::Demangler);
        }
        if s.eq_ignore_ascii_case("analyzeDataFlow")
            || s.eq_ignore_ascii_case("analyze_data_flow")
        {
            return Ok(Self::AnalyzeDataFlow);
        }
        if s.eq_ignore_ascii_case("showDataFlow")
            || s.eq_ignore_ascii_case("show_data_flow")
        {
            return Ok(Self::ShowDataFlow);
        }
        if s.eq_ignore_ascii_case("spaceBetweenArgs")
            || s.eq_ignore_ascii_case("space_between_args")
        {
            return Ok(Self::SpaceBetweenArgs);
        }
        if s.eq_ignore_ascii_case("showSymbolSizes")
            || s.eq_ignore_ascii_case("show_symbol_sizes")
        {
            return Ok(Self::ShowSymbolSizes);
        }
        if s.eq_ignore_ascii_case("combineDataSections")
            || s.eq_ignore_ascii_case("combine_data_sections")
        {
            return Ok(Self::CombineDataSections);
        }
        if s.eq_ignore_ascii_case("combineTextSections")
            || s.eq_ignore_ascii_case("combine_text_sections")
        {
            return Ok(Self::CombineTextSections);
        }
        if s.eq_ignore_ascii_case("preferredStringEncoding")
            || s.eq_ignore_ascii_case("preferred_string_encoding")
        {
            return Ok(Self::PreferredStringEncoding);
        }
        if s.eq_ignore_ascii_case("arm.archVersion")
            || s.eq_ignore_ascii_case("arm_arch_version")
        {
            return Ok(Self::ArmArchVersion);
        }
        if s.eq_ignore_ascii_case("arm.vfpV2") || s.eq_ignore_ascii_case("arm_vfp_v2") {
            return Ok(Self::ArmVfpV2);
        }
        if s.eq_ignore_ascii_case("arm.unifiedSyntax")
            || s.eq_ignore_ascii_case("arm_unified_syntax")
        {
            return Ok(Self::ArmUnifiedSyntax);
        }
        if s.eq_ignore_ascii_case("arm.avRegisters")
            || s.eq_ignore_ascii_case("arm_av_registers")
        {
            return Ok(Self::ArmAvRegisters);
        }
        if s.eq_ignore_ascii_case("arm.r9Usage")
            || s.eq_ignore_ascii_case("arm_r9_usage")
        {
            return Ok(Self::ArmR9Usage);
        }
        if s.eq_ignore_ascii_case("arm.slUsage")
            || s.eq_ignore_ascii_case("arm_sl_usage")
        {
            return Ok(Self::ArmSlUsage);
        }
        if s.eq_ignore_ascii_case("arm.fpUsage")
            || s.eq_ignore_ascii_case("arm_fp_usage")
        {
            return Ok(Self::ArmFpUsage);
        }
        if s.eq_ignore_ascii_case("arm.ipUsage")
            || s.eq_ignore_ascii_case("arm_ip_usage")
        {
            return Ok(Self::ArmIpUsage);
        }
        if s.eq_ignore_ascii_case("mips.abi") || s.eq_ignore_ascii_case("mips_abi") {
            return Ok(Self::MipsAbi);
        }
        if s.eq_ignore_ascii_case("mips.instrCategory")
            || s.eq_ignore_ascii_case("mips_instr_category")
        {
            return Ok(Self::MipsInstrCategory);
        }
        if s.eq_ignore_ascii_case("mips.registerPrefix")
            || s.eq_ignore_ascii_case("mips_register_prefix")
        {
            return Ok(Self::MipsRegisterPrefix);
        }
        if s.eq_ignore_ascii_case("mips.prodgSnAsInvertedRegs")
            || s.eq_ignore_ascii_case("mips_prodg_sn_as_inverted_regs")
        {
            return Ok(Self::MipsProdgSnAsInvertedRegs);
        }
        if s.eq_ignore_ascii_case("ppc.calculatePoolRelocations")
            || s.eq_ignore_ascii_case("ppc_calculate_pool_relocations")
        {
            return Ok(Self::PpcCalculatePoolRelocations);
        }
        if s.eq_ignore_ascii_case("x86.formatter")
            || s.eq_ignore_ascii_case("x86_formatter")
        {
            return Ok(Self::X86Formatter);
        }
        Err(())
    }
}
#[derive(Clone, Debug)]
pub struct ConfigPropertyGroup {
    pub id: &'static str,
    pub name: &'static str,
    pub description: Option<&'static str>,
    pub properties: &'static [ConfigPropertyId],
}
pub static CONFIG_GROUPS: &[ConfigPropertyGroup] = &[
    ConfigPropertyGroup {
        id: "general",
        name: "General",
        description: None,
        properties: &[
            ConfigPropertyId::PreferredStringEncoding,
            ConfigPropertyId::FunctionRelocDiffs,
            ConfigPropertyId::Demangler,
            ConfigPropertyId::ShowSymbolSizes,
            ConfigPropertyId::SpaceBetweenArgs,
            ConfigPropertyId::CombineDataSections,
            ConfigPropertyId::CombineTextSections,
        ],
    },
    ConfigPropertyGroup {
        id: "arm",
        name: "ARM",
        description: None,
        properties: &[
            ConfigPropertyId::ArmArchVersion,
            ConfigPropertyId::ArmVfpV2,
            ConfigPropertyId::ArmUnifiedSyntax,
            ConfigPropertyId::ArmAvRegisters,
            ConfigPropertyId::ArmR9Usage,
            ConfigPropertyId::ArmSlUsage,
            ConfigPropertyId::ArmFpUsage,
            ConfigPropertyId::ArmIpUsage,
        ],
    },
    ConfigPropertyGroup {
        id: "mips",
        name: "MIPS",
        description: None,
        properties: &[
            ConfigPropertyId::MipsAbi,
            ConfigPropertyId::MipsInstrCategory,
            ConfigPropertyId::MipsRegisterPrefix,
            ConfigPropertyId::MipsProdgSnAsInvertedRegs,
        ],
    },
    ConfigPropertyGroup {
        id: "ppc",
        name: "PowerPC",
        description: None,
        properties: &[
            ConfigPropertyId::PpcCalculatePoolRelocations,
            ConfigPropertyId::AnalyzeDataFlow,
        ],
    },
    ConfigPropertyGroup {
        id: "x86",
        name: "x86",
        description: None,
        properties: &[ConfigPropertyId::X86Formatter],
    },
];
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum ConfigPropertyValue {
    Boolean(bool),
    Choice(&'static str),
}
impl ConfigPropertyValue {
    #[cfg(feature = "serde")]
    pub fn to_json(&self) -> serde_json::Value {
        match self {
            ConfigPropertyValue::Boolean(value) => serde_json::Value::Bool(*value),
            ConfigPropertyValue::Choice(value) => {
                serde_json::Value::String(value.to_string())
            }
        }
    }
}
impl core::fmt::Display for ConfigPropertyValue {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match *self {
            ConfigPropertyValue::Boolean(value) => write!(f, "{value}"),
            ConfigPropertyValue::Choice(value) => f.write_str(value),
        }
    }
}
#[derive(Clone, Debug)]
pub enum ConfigPropertyKind {
    Boolean,
    Choice(&'static [ConfigEnumVariantInfo]),
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum FunctionRelocDiffs {
    /// None
    #[cfg_attr(feature = "serde", serde(rename = "none", alias = "None"))]
    None,
    /// Name or address
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "name_address", alias = "NameAddress"))]
    NameAddress,
    /// Data value
    #[cfg_attr(feature = "serde", serde(rename = "data_value", alias = "DataValue"))]
    DataValue,
    /// Name or address, data value
    #[cfg_attr(feature = "serde", serde(rename = "all", alias = "All"))]
    All,
}
impl ConfigEnum for FunctionRelocDiffs {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[FunctionRelocDiffs] = &[
            FunctionRelocDiffs::None,
            FunctionRelocDiffs::NameAddress,
            FunctionRelocDiffs::DataValue,
            FunctionRelocDiffs::All,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "none",
                name: "None",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "name_address",
                name: "Name or address",
                description: None,
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "data_value",
                name: "Data value",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "all",
                name: "Name or address, data value",
                description: None,
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            FunctionRelocDiffs::None => "none",
            FunctionRelocDiffs::NameAddress => "name_address",
            FunctionRelocDiffs::DataValue => "data_value",
            FunctionRelocDiffs::All => "all",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            FunctionRelocDiffs::None => "None",
            FunctionRelocDiffs::NameAddress => "Name or address",
            FunctionRelocDiffs::DataValue => "Data value",
            FunctionRelocDiffs::All => "Name or address, data value",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            FunctionRelocDiffs::None => None,
            FunctionRelocDiffs::NameAddress => None,
            FunctionRelocDiffs::DataValue => None,
            FunctionRelocDiffs::All => None,
        }
    }
}
impl core::str::FromStr for FunctionRelocDiffs {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("none") {
            return Ok(FunctionRelocDiffs::None);
        }
        if s.eq_ignore_ascii_case("name_address") {
            return Ok(FunctionRelocDiffs::NameAddress);
        }
        if s.eq_ignore_ascii_case("data_value") {
            return Ok(FunctionRelocDiffs::DataValue);
        }
        if s.eq_ignore_ascii_case("all") {
            return Ok(FunctionRelocDiffs::All);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum Demangler {
    /// Auto
    ///
    /// Try to automatically guess the mangling format.
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "auto", alias = "Auto"))]
    Auto,
    /// None
    ///
    /// Disable demangling.
    #[cfg_attr(feature = "serde", serde(rename = "none", alias = "None"))]
    None,
    /// CodeWarrior
    #[cfg_attr(feature = "serde", serde(rename = "codewarrior", alias = "Codewarrior"))]
    Codewarrior,
    /// Itanium
    #[cfg_attr(feature = "serde", serde(rename = "itanium", alias = "Itanium"))]
    Itanium,
    /// MSVC
    #[cfg_attr(feature = "serde", serde(rename = "msvc", alias = "Msvc"))]
    Msvc,
    /// GNU g++ (Legacy)
    ///
    /// Use the old GNU mangling ABI. Used up to g++ 2.9.x
    #[cfg_attr(feature = "serde", serde(rename = "gnu_legacy", alias = "GnuLegacy"))]
    GnuLegacy,
}
impl ConfigEnum for Demangler {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[Demangler] = &[
            Demangler::Auto,
            Demangler::None,
            Demangler::Codewarrior,
            Demangler::Itanium,
            Demangler::Msvc,
            Demangler::GnuLegacy,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "auto",
                name: "Auto",
                description: Some("Try to automatically guess the mangling format."),
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "none",
                name: "None",
                description: Some("Disable demangling."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "codewarrior",
                name: "CodeWarrior",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "itanium",
                name: "Itanium",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "msvc",
                name: "MSVC",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "gnu_legacy",
                name: "GNU g++ (Legacy)",
                description: Some("Use the old GNU mangling ABI. Used up to g++ 2.9.x"),
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            Demangler::Auto => "auto",
            Demangler::None => "none",
            Demangler::Codewarrior => "codewarrior",
            Demangler::Itanium => "itanium",
            Demangler::Msvc => "msvc",
            Demangler::GnuLegacy => "gnu_legacy",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            Demangler::Auto => "Auto",
            Demangler::None => "None",
            Demangler::Codewarrior => "CodeWarrior",
            Demangler::Itanium => "Itanium",
            Demangler::Msvc => "MSVC",
            Demangler::GnuLegacy => "GNU g++ (Legacy)",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            Demangler::Auto => Some("Try to automatically guess the mangling format."),
            Demangler::None => Some("Disable demangling."),
            Demangler::Codewarrior => None,
            Demangler::Itanium => None,
            Demangler::Msvc => None,
            Demangler::GnuLegacy => {
                Some("Use the old GNU mangling ABI. Used up to g++ 2.9.x")
            }
        }
    }
}
impl core::str::FromStr for Demangler {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("auto") {
            return Ok(Demangler::Auto);
        }
        if s.eq_ignore_ascii_case("none") {
            return Ok(Demangler::None);
        }
        if s.eq_ignore_ascii_case("codewarrior") {
            return Ok(Demangler::Codewarrior);
        }
        if s.eq_ignore_ascii_case("itanium") {
            return Ok(Demangler::Itanium);
        }
        if s.eq_ignore_ascii_case("msvc") {
            return Ok(Demangler::Msvc);
        }
        if s.eq_ignore_ascii_case("gnu_legacy") {
            return Ok(Demangler::GnuLegacy);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ShowSymbolSizes {
    /// Off
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "off", alias = "Off"))]
    Off,
    /// Hex
    #[cfg_attr(feature = "serde", serde(rename = "hex", alias = "Hex"))]
    Hex,
    /// Decimal
    #[cfg_attr(feature = "serde", serde(rename = "decimal", alias = "Decimal"))]
    Decimal,
}
impl ConfigEnum for ShowSymbolSizes {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[ShowSymbolSizes] = &[
            ShowSymbolSizes::Off,
            ShowSymbolSizes::Hex,
            ShowSymbolSizes::Decimal,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "off",
                name: "Off",
                description: None,
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "hex",
                name: "Hex",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "decimal",
                name: "Decimal",
                description: None,
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            ShowSymbolSizes::Off => "off",
            ShowSymbolSizes::Hex => "hex",
            ShowSymbolSizes::Decimal => "decimal",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            ShowSymbolSizes::Off => "Off",
            ShowSymbolSizes::Hex => "Hex",
            ShowSymbolSizes::Decimal => "Decimal",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            ShowSymbolSizes::Off => None,
            ShowSymbolSizes::Hex => None,
            ShowSymbolSizes::Decimal => None,
        }
    }
}
impl core::str::FromStr for ShowSymbolSizes {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("off") {
            return Ok(ShowSymbolSizes::Off);
        }
        if s.eq_ignore_ascii_case("hex") {
            return Ok(ShowSymbolSizes::Hex);
        }
        if s.eq_ignore_ascii_case("decimal") {
            return Ok(ShowSymbolSizes::Decimal);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum PreferredStringEncoding {
    /// Auto
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "auto", alias = "Auto"))]
    Auto,
    /// ASCII
    #[cfg_attr(feature = "serde", serde(rename = "ascii", alias = "Ascii"))]
    Ascii,
    /// UTF-8
    #[cfg_attr(feature = "serde", serde(rename = "utf_8", alias = "Utf8"))]
    Utf8,
    /// Shift JIS
    #[cfg_attr(feature = "serde", serde(rename = "shift_jis", alias = "ShiftJis"))]
    ShiftJis,
    /// Windows-1252
    #[cfg_attr(feature = "serde", serde(rename = "windows_1252", alias = "Windows1252"))]
    Windows1252,
    /// EUC-JP
    #[cfg_attr(feature = "serde", serde(rename = "euc_jp", alias = "EucJp"))]
    EucJp,
    /// Big5
    #[cfg_attr(feature = "serde", serde(rename = "big5", alias = "Big5"))]
    Big5,
    /// UTF-16BE
    #[cfg_attr(feature = "serde", serde(rename = "utf_16be", alias = "Utf16be"))]
    Utf16be,
    /// UTF-16LE
    #[cfg_attr(feature = "serde", serde(rename = "utf_16le", alias = "Utf16le"))]
    Utf16le,
}
impl ConfigEnum for PreferredStringEncoding {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[PreferredStringEncoding] = &[
            PreferredStringEncoding::Auto,
            PreferredStringEncoding::Ascii,
            PreferredStringEncoding::Utf8,
            PreferredStringEncoding::ShiftJis,
            PreferredStringEncoding::Windows1252,
            PreferredStringEncoding::EucJp,
            PreferredStringEncoding::Big5,
            PreferredStringEncoding::Utf16be,
            PreferredStringEncoding::Utf16le,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "auto",
                name: "Auto",
                description: None,
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "ascii",
                name: "ASCII",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "utf_8",
                name: "UTF-8",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "shift_jis",
                name: "Shift JIS",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "windows_1252",
                name: "Windows-1252",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "euc_jp",
                name: "EUC-JP",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "big5",
                name: "Big5",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "utf_16be",
                name: "UTF-16BE",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "utf_16le",
                name: "UTF-16LE",
                description: None,
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            PreferredStringEncoding::Auto => "auto",
            PreferredStringEncoding::Ascii => "ascii",
            PreferredStringEncoding::Utf8 => "utf_8",
            PreferredStringEncoding::ShiftJis => "shift_jis",
            PreferredStringEncoding::Windows1252 => "windows_1252",
            PreferredStringEncoding::EucJp => "euc_jp",
            PreferredStringEncoding::Big5 => "big5",
            PreferredStringEncoding::Utf16be => "utf_16be",
            PreferredStringEncoding::Utf16le => "utf_16le",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            PreferredStringEncoding::Auto => "Auto",
            PreferredStringEncoding::Ascii => "ASCII",
            PreferredStringEncoding::Utf8 => "UTF-8",
            PreferredStringEncoding::ShiftJis => "Shift JIS",
            PreferredStringEncoding::Windows1252 => "Windows-1252",
            PreferredStringEncoding::EucJp => "EUC-JP",
            PreferredStringEncoding::Big5 => "Big5",
            PreferredStringEncoding::Utf16be => "UTF-16BE",
            PreferredStringEncoding::Utf16le => "UTF-16LE",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            PreferredStringEncoding::Auto => None,
            PreferredStringEncoding::Ascii => None,
            PreferredStringEncoding::Utf8 => None,
            PreferredStringEncoding::ShiftJis => None,
            PreferredStringEncoding::Windows1252 => None,
            PreferredStringEncoding::EucJp => None,
            PreferredStringEncoding::Big5 => None,
            PreferredStringEncoding::Utf16be => None,
            PreferredStringEncoding::Utf16le => None,
        }
    }
}
impl core::str::FromStr for PreferredStringEncoding {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("auto") {
            return Ok(PreferredStringEncoding::Auto);
        }
        if s.eq_ignore_ascii_case("ascii") {
            return Ok(PreferredStringEncoding::Ascii);
        }
        if s.eq_ignore_ascii_case("utf_8") {
            return Ok(PreferredStringEncoding::Utf8);
        }
        if s.eq_ignore_ascii_case("shift_jis") {
            return Ok(PreferredStringEncoding::ShiftJis);
        }
        if s.eq_ignore_ascii_case("windows_1252") {
            return Ok(PreferredStringEncoding::Windows1252);
        }
        if s.eq_ignore_ascii_case("euc_jp") {
            return Ok(PreferredStringEncoding::EucJp);
        }
        if s.eq_ignore_ascii_case("big5") {
            return Ok(PreferredStringEncoding::Big5);
        }
        if s.eq_ignore_ascii_case("utf_16be") {
            return Ok(PreferredStringEncoding::Utf16be);
        }
        if s.eq_ignore_ascii_case("utf_16le") {
            return Ok(PreferredStringEncoding::Utf16le);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ArmArchVersion {
    /// Auto
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "auto", alias = "Auto"))]
    Auto,
    /// ARMv4
    #[cfg_attr(feature = "serde", serde(rename = "v4", alias = "V4"))]
    V4,
    /// ARMv4T (GBA)
    #[cfg_attr(feature = "serde", serde(rename = "v4t", alias = "V4t"))]
    V4t,
    /// ARMv5T
    #[cfg_attr(feature = "serde", serde(rename = "v5t", alias = "V5t"))]
    V5t,
    /// ARMv5TE (DS)
    #[cfg_attr(feature = "serde", serde(rename = "v5te", alias = "V5te"))]
    V5te,
    /// ARMv5TEJ
    #[cfg_attr(feature = "serde", serde(rename = "v5tej", alias = "V5tej"))]
    V5tej,
    /// ARMv6
    #[cfg_attr(feature = "serde", serde(rename = "v6", alias = "V6"))]
    V6,
    /// ARMv6K (3DS)
    #[cfg_attr(feature = "serde", serde(rename = "v6k", alias = "V6k"))]
    V6k,
}
impl ConfigEnum for ArmArchVersion {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[ArmArchVersion] = &[
            ArmArchVersion::Auto,
            ArmArchVersion::V4,
            ArmArchVersion::V4t,
            ArmArchVersion::V5t,
            ArmArchVersion::V5te,
            ArmArchVersion::V5tej,
            ArmArchVersion::V6,
            ArmArchVersion::V6k,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "auto",
                name: "Auto",
                description: None,
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "v4",
                name: "ARMv4",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "v4t",
                name: "ARMv4T (GBA)",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "v5t",
                name: "ARMv5T",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "v5te",
                name: "ARMv5TE (DS)",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "v5tej",
                name: "ARMv5TEJ",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "v6",
                name: "ARMv6",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "v6k",
                name: "ARMv6K (3DS)",
                description: None,
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            ArmArchVersion::Auto => "auto",
            ArmArchVersion::V4 => "v4",
            ArmArchVersion::V4t => "v4t",
            ArmArchVersion::V5t => "v5t",
            ArmArchVersion::V5te => "v5te",
            ArmArchVersion::V5tej => "v5tej",
            ArmArchVersion::V6 => "v6",
            ArmArchVersion::V6k => "v6k",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            ArmArchVersion::Auto => "Auto",
            ArmArchVersion::V4 => "ARMv4",
            ArmArchVersion::V4t => "ARMv4T (GBA)",
            ArmArchVersion::V5t => "ARMv5T",
            ArmArchVersion::V5te => "ARMv5TE (DS)",
            ArmArchVersion::V5tej => "ARMv5TEJ",
            ArmArchVersion::V6 => "ARMv6",
            ArmArchVersion::V6k => "ARMv6K (3DS)",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            ArmArchVersion::Auto => None,
            ArmArchVersion::V4 => None,
            ArmArchVersion::V4t => None,
            ArmArchVersion::V5t => None,
            ArmArchVersion::V5te => None,
            ArmArchVersion::V5tej => None,
            ArmArchVersion::V6 => None,
            ArmArchVersion::V6k => None,
        }
    }
}
impl core::str::FromStr for ArmArchVersion {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("auto") {
            return Ok(ArmArchVersion::Auto);
        }
        if s.eq_ignore_ascii_case("v4") {
            return Ok(ArmArchVersion::V4);
        }
        if s.eq_ignore_ascii_case("v4t") {
            return Ok(ArmArchVersion::V4t);
        }
        if s.eq_ignore_ascii_case("v5t") {
            return Ok(ArmArchVersion::V5t);
        }
        if s.eq_ignore_ascii_case("v5te") {
            return Ok(ArmArchVersion::V5te);
        }
        if s.eq_ignore_ascii_case("v5tej") {
            return Ok(ArmArchVersion::V5tej);
        }
        if s.eq_ignore_ascii_case("v6") {
            return Ok(ArmArchVersion::V6);
        }
        if s.eq_ignore_ascii_case("v6k") {
            return Ok(ArmArchVersion::V6k);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum ArmR9Usage {
    /// R9 or V6
    ///
    /// Use R9 as a general-purpose register.
    #[default]
    #[cfg_attr(
        feature = "serde",
        serde(rename = "generalPurpose", alias = "GeneralPurpose")
    )]
    GeneralPurpose,
    /// SB (static base)
    ///
    /// Used for position-independent data (PID).
    #[cfg_attr(feature = "serde", serde(rename = "sb", alias = "Sb"))]
    Sb,
    /// TR (TLS register)
    ///
    /// Used for thread-local storage.
    #[cfg_attr(feature = "serde", serde(rename = "tr", alias = "Tr"))]
    Tr,
}
impl ConfigEnum for ArmR9Usage {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[ArmR9Usage] = &[
            ArmR9Usage::GeneralPurpose,
            ArmR9Usage::Sb,
            ArmR9Usage::Tr,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "generalPurpose",
                name: "R9 or V6",
                description: Some("Use R9 as a general-purpose register."),
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "sb",
                name: "SB (static base)",
                description: Some("Used for position-independent data (PID)."),
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "tr",
                name: "TR (TLS register)",
                description: Some("Used for thread-local storage."),
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            ArmR9Usage::GeneralPurpose => "generalPurpose",
            ArmR9Usage::Sb => "sb",
            ArmR9Usage::Tr => "tr",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            ArmR9Usage::GeneralPurpose => "R9 or V6",
            ArmR9Usage::Sb => "SB (static base)",
            ArmR9Usage::Tr => "TR (TLS register)",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            ArmR9Usage::GeneralPurpose => Some("Use R9 as a general-purpose register."),
            ArmR9Usage::Sb => Some("Used for position-independent data (PID)."),
            ArmR9Usage::Tr => Some("Used for thread-local storage."),
        }
    }
}
impl core::str::FromStr for ArmR9Usage {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("generalPurpose") {
            return Ok(ArmR9Usage::GeneralPurpose);
        }
        if s.eq_ignore_ascii_case("sb") {
            return Ok(ArmR9Usage::Sb);
        }
        if s.eq_ignore_ascii_case("tr") {
            return Ok(ArmR9Usage::Tr);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum MipsAbi {
    /// Auto
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "auto", alias = "Auto"))]
    Auto,
    /// O32
    #[cfg_attr(feature = "serde", serde(rename = "o32", alias = "O32"))]
    O32,
    /// O64
    #[cfg_attr(feature = "serde", serde(rename = "o64", alias = "O64"))]
    O64,
    /// N32
    #[cfg_attr(feature = "serde", serde(rename = "n32", alias = "N32"))]
    N32,
    /// N64
    #[cfg_attr(feature = "serde", serde(rename = "n64", alias = "N64"))]
    N64,
    /// eabi32
    #[cfg_attr(feature = "serde", serde(rename = "eabi32", alias = "Eabi32"))]
    Eabi32,
    /// eabi64
    #[cfg_attr(feature = "serde", serde(rename = "eabi64", alias = "Eabi64"))]
    Eabi64,
}
impl ConfigEnum for MipsAbi {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[MipsAbi] = &[
            MipsAbi::Auto,
            MipsAbi::O32,
            MipsAbi::O64,
            MipsAbi::N32,
            MipsAbi::N64,
            MipsAbi::Eabi32,
            MipsAbi::Eabi64,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "auto",
                name: "Auto",
                description: None,
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "o32",
                name: "O32",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "o64",
                name: "O64",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "n32",
                name: "N32",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "n64",
                name: "N64",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "eabi32",
                name: "eabi32",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "eabi64",
                name: "eabi64",
                description: None,
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            MipsAbi::Auto => "auto",
            MipsAbi::O32 => "o32",
            MipsAbi::O64 => "o64",
            MipsAbi::N32 => "n32",
            MipsAbi::N64 => "n64",
            MipsAbi::Eabi32 => "eabi32",
            MipsAbi::Eabi64 => "eabi64",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            MipsAbi::Auto => "Auto",
            MipsAbi::O32 => "O32",
            MipsAbi::O64 => "O64",
            MipsAbi::N32 => "N32",
            MipsAbi::N64 => "N64",
            MipsAbi::Eabi32 => "eabi32",
            MipsAbi::Eabi64 => "eabi64",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            MipsAbi::Auto => None,
            MipsAbi::O32 => None,
            MipsAbi::O64 => None,
            MipsAbi::N32 => None,
            MipsAbi::N64 => None,
            MipsAbi::Eabi32 => None,
            MipsAbi::Eabi64 => None,
        }
    }
}
impl core::str::FromStr for MipsAbi {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("auto") {
            return Ok(MipsAbi::Auto);
        }
        if s.eq_ignore_ascii_case("o32") {
            return Ok(MipsAbi::O32);
        }
        if s.eq_ignore_ascii_case("o64") {
            return Ok(MipsAbi::O64);
        }
        if s.eq_ignore_ascii_case("n32") {
            return Ok(MipsAbi::N32);
        }
        if s.eq_ignore_ascii_case("n64") {
            return Ok(MipsAbi::N64);
        }
        if s.eq_ignore_ascii_case("eabi32") {
            return Ok(MipsAbi::Eabi32);
        }
        if s.eq_ignore_ascii_case("eabi64") {
            return Ok(MipsAbi::Eabi64);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum MipsInstrCategory {
    /// Auto
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "auto", alias = "Auto"))]
    Auto,
    /// CPU
    #[cfg_attr(feature = "serde", serde(rename = "cpu", alias = "Cpu"))]
    Cpu,
    /// RSP (N64)
    #[cfg_attr(feature = "serde", serde(rename = "rsp", alias = "Rsp"))]
    Rsp,
    /// R3000 GTE (PS1)
    #[cfg_attr(feature = "serde", serde(rename = "r3000gte", alias = "R3000gte"))]
    R3000gte,
    /// R4000 ALLEGREX (PSP)
    #[cfg_attr(
        feature = "serde",
        serde(rename = "r4000allegrex", alias = "R4000allegrex")
    )]
    R4000allegrex,
    /// R5900 EE (PS2)
    #[cfg_attr(feature = "serde", serde(rename = "r5900", alias = "R5900"))]
    R5900,
}
impl ConfigEnum for MipsInstrCategory {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[MipsInstrCategory] = &[
            MipsInstrCategory::Auto,
            MipsInstrCategory::Cpu,
            MipsInstrCategory::Rsp,
            MipsInstrCategory::R3000gte,
            MipsInstrCategory::R4000allegrex,
            MipsInstrCategory::R5900,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "auto",
                name: "Auto",
                description: None,
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "cpu",
                name: "CPU",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "rsp",
                name: "RSP (N64)",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "r3000gte",
                name: "R3000 GTE (PS1)",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "r4000allegrex",
                name: "R4000 ALLEGREX (PSP)",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "r5900",
                name: "R5900 EE (PS2)",
                description: None,
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            MipsInstrCategory::Auto => "auto",
            MipsInstrCategory::Cpu => "cpu",
            MipsInstrCategory::Rsp => "rsp",
            MipsInstrCategory::R3000gte => "r3000gte",
            MipsInstrCategory::R4000allegrex => "r4000allegrex",
            MipsInstrCategory::R5900 => "r5900",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            MipsInstrCategory::Auto => "Auto",
            MipsInstrCategory::Cpu => "CPU",
            MipsInstrCategory::Rsp => "RSP (N64)",
            MipsInstrCategory::R3000gte => "R3000 GTE (PS1)",
            MipsInstrCategory::R4000allegrex => "R4000 ALLEGREX (PSP)",
            MipsInstrCategory::R5900 => "R5900 EE (PS2)",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            MipsInstrCategory::Auto => None,
            MipsInstrCategory::Cpu => None,
            MipsInstrCategory::Rsp => None,
            MipsInstrCategory::R3000gte => None,
            MipsInstrCategory::R4000allegrex => None,
            MipsInstrCategory::R5900 => None,
        }
    }
}
impl core::str::FromStr for MipsInstrCategory {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("auto") {
            return Ok(MipsInstrCategory::Auto);
        }
        if s.eq_ignore_ascii_case("cpu") {
            return Ok(MipsInstrCategory::Cpu);
        }
        if s.eq_ignore_ascii_case("rsp") {
            return Ok(MipsInstrCategory::Rsp);
        }
        if s.eq_ignore_ascii_case("r3000gte") {
            return Ok(MipsInstrCategory::R3000gte);
        }
        if s.eq_ignore_ascii_case("r4000allegrex") {
            return Ok(MipsInstrCategory::R4000allegrex);
        }
        if s.eq_ignore_ascii_case("r5900") {
            return Ok(MipsInstrCategory::R5900);
        }
        Err(())
    }
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum X86Formatter {
    /// Intel
    #[default]
    #[cfg_attr(feature = "serde", serde(rename = "intel", alias = "Intel"))]
    Intel,
    /// AT&T
    #[cfg_attr(feature = "serde", serde(rename = "gas", alias = "Gas"))]
    Gas,
    /// NASM
    #[cfg_attr(feature = "serde", serde(rename = "nasm", alias = "Nasm"))]
    Nasm,
    /// MASM
    #[cfg_attr(feature = "serde", serde(rename = "masm", alias = "Masm"))]
    Masm,
}
impl ConfigEnum for X86Formatter {
    #[inline]
    fn variants() -> &'static [Self] {
        static VARIANTS: &[X86Formatter] = &[
            X86Formatter::Intel,
            X86Formatter::Gas,
            X86Formatter::Nasm,
            X86Formatter::Masm,
        ];
        VARIANTS
    }
    #[inline]
    fn variant_info() -> &'static [ConfigEnumVariantInfo] {
        static VARIANT_INFO: &[ConfigEnumVariantInfo] = &[
            ConfigEnumVariantInfo {
                value: "intel",
                name: "Intel",
                description: None,
                is_default: true,
            },
            ConfigEnumVariantInfo {
                value: "gas",
                name: "AT&T",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "nasm",
                name: "NASM",
                description: None,
                is_default: false,
            },
            ConfigEnumVariantInfo {
                value: "masm",
                name: "MASM",
                description: None,
                is_default: false,
            },
        ];
        VARIANT_INFO
    }
    fn as_str(&self) -> &'static str {
        match self {
            X86Formatter::Intel => "intel",
            X86Formatter::Gas => "gas",
            X86Formatter::Nasm => "nasm",
            X86Formatter::Masm => "masm",
        }
    }
    fn name(&self) -> &'static str {
        match self {
            X86Formatter::Intel => "Intel",
            X86Formatter::Gas => "AT&T",
            X86Formatter::Nasm => "NASM",
            X86Formatter::Masm => "MASM",
        }
    }
    fn description(&self) -> Option<&'static str> {
        match self {
            X86Formatter::Intel => None,
            X86Formatter::Gas => None,
            X86Formatter::Nasm => None,
            X86Formatter::Masm => None,
        }
    }
}
impl core::str::FromStr for X86Formatter {
    type Err = ();
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        if s.eq_ignore_ascii_case("intel") {
            return Ok(X86Formatter::Intel);
        }
        if s.eq_ignore_ascii_case("gas") {
            return Ok(X86Formatter::Gas);
        }
        if s.eq_ignore_ascii_case("nasm") {
            return Ok(X86Formatter::Nasm);
        }
        if s.eq_ignore_ascii_case("masm") {
            return Ok(X86Formatter::Masm);
        }
        Err(())
    }
}
#[cfg(feature = "serde")]
#[inline(always)]
fn default_true() -> bool {
    true
}
#[derive(Clone, Debug)]
#[cfg_attr(
    feature = "serde",
    derive(serde::Deserialize, serde::Serialize),
    serde(default)
)]
pub struct DiffObjConfig {
    /// Function relocation diffs
    ///
    /// How relocation targets will be diffed in the function view.
    pub function_reloc_diffs: FunctionRelocDiffs,
    /// Demangler
    ///
    /// Which demangler should be used to demangle each symbol.
    pub demangler: Demangler,
    /// (Experimental) Perform data flow analysis
    ///
    /// Use data flow analysis to display known information about register contents where possible
    pub analyze_data_flow: bool,
    /// Show data flow
    ///
    /// Show data flow analysis results in place of register name where present
    #[cfg_attr(feature = "serde", serde(default = "default_true"))]
    pub show_data_flow: bool,
    /// Space between args
    ///
    /// Adds a space between arguments in the diff output.
    #[cfg_attr(feature = "serde", serde(default = "default_true"))]
    pub space_between_args: bool,
    /// Show symbol sizes
    ///
    /// Shows symbol sizes in the symbol view.
    pub show_symbol_sizes: ShowSymbolSizes,
    /// Combine data sections
    ///
    /// Combines data sections with equal names.
    pub combine_data_sections: bool,
    /// Combine text sections
    ///
    /// Combines all text sections into one.
    pub combine_text_sections: bool,
    /// Preferred string encoding
    ///
    /// Which encoding to use when diffing string literals used in functions.
    pub preferred_string_encoding: PreferredStringEncoding,
    /// Architecture version
    ///
    /// ARM architecture version to use for disassembly.
    pub arm_arch_version: ArmArchVersion,
    /// VFPv2 instructions
    ///
    /// Adds floating-point instructions from VFPv2.
    #[cfg_attr(feature = "serde", serde(default = "default_true"))]
    pub arm_vfp_v2: bool,
    /// Unified syntax
    ///
    /// Disassemble as unified assembly language (UAL).
    pub arm_unified_syntax: bool,
    /// Use A/V registers
    ///
    /// Display R0-R3 as A1-A4 and R4-R11 as V1-V8.
    pub arm_av_registers: bool,
    /// Display R9 as
    pub arm_r9_usage: ArmR9Usage,
    /// Display R10 as SL
    ///
    /// Used for explicit stack limits.
    pub arm_sl_usage: bool,
    /// Display R11 as FP
    ///
    /// Used for frame pointers.
    pub arm_fp_usage: bool,
    /// Display R12 as IP
    ///
    /// Used for interworking and long branches.
    pub arm_ip_usage: bool,
    /// ABI
    ///
    /// MIPS ABI to use for disassembly.
    pub mips_abi: MipsAbi,
    /// Instruction category
    ///
    /// MIPS instruction category to use for disassembly.
    pub mips_instr_category: MipsInstrCategory,
    /// Register '$' prefix
    ///
    /// Display MIPS register names with a '$' prefix.
    pub mips_register_prefix: bool,
    /// ProDG SN AS VU register order
    ///
    /// Changes the register order for specific R5900EE instructions to match the syntax used by the SN AS from ProDG (-snas flag).
    pub mips_prodg_sn_as_inverted_regs: bool,
    /// Calculate pooled data references
    ///
    /// Display pooled data references in functions as fake relocations.
    #[cfg_attr(feature = "serde", serde(default = "default_true"))]
    pub ppc_calculate_pool_relocations: bool,
    /// Format
    ///
    /// x86 disassembly syntax.
    pub x86_formatter: X86Formatter,
}
impl Default for DiffObjConfig {
    fn default() -> Self {
        Self {
            function_reloc_diffs: FunctionRelocDiffs::default(),
            demangler: Demangler::default(),
            analyze_data_flow: false,
            show_data_flow: true,
            space_between_args: true,
            show_symbol_sizes: ShowSymbolSizes::default(),
            combine_data_sections: false,
            combine_text_sections: false,
            preferred_string_encoding: PreferredStringEncoding::default(),
            arm_arch_version: ArmArchVersion::default(),
            arm_vfp_v2: true,
            arm_unified_syntax: false,
            arm_av_registers: false,
            arm_r9_usage: ArmR9Usage::default(),
            arm_sl_usage: false,
            arm_fp_usage: false,
            arm_ip_usage: false,
            mips_abi: MipsAbi::default(),
            mips_instr_category: MipsInstrCategory::default(),
            mips_register_prefix: false,
            mips_prodg_sn_as_inverted_regs: false,
            ppc_calculate_pool_relocations: true,
            x86_formatter: X86Formatter::default(),
        }
    }
}
impl DiffObjConfig {
    pub fn get_property_value(&self, id: ConfigPropertyId) -> ConfigPropertyValue {
        match id {
            ConfigPropertyId::FunctionRelocDiffs => {
                ConfigPropertyValue::Choice(self.function_reloc_diffs.as_str())
            }
            ConfigPropertyId::Demangler => {
                ConfigPropertyValue::Choice(self.demangler.as_str())
            }
            ConfigPropertyId::AnalyzeDataFlow => {
                ConfigPropertyValue::Boolean(self.analyze_data_flow)
            }
            ConfigPropertyId::ShowDataFlow => {
                ConfigPropertyValue::Boolean(self.show_data_flow)
            }
            ConfigPropertyId::SpaceBetweenArgs => {
                ConfigPropertyValue::Boolean(self.space_between_args)
            }
            ConfigPropertyId::ShowSymbolSizes => {
                ConfigPropertyValue::Choice(self.show_symbol_sizes.as_str())
            }
            ConfigPropertyId::CombineDataSections => {
                ConfigPropertyValue::Boolean(self.combine_data_sections)
            }
            ConfigPropertyId::CombineTextSections => {
                ConfigPropertyValue::Boolean(self.combine_text_sections)
            }
            ConfigPropertyId::PreferredStringEncoding => {
                ConfigPropertyValue::Choice(self.preferred_string_encoding.as_str())
            }
            ConfigPropertyId::ArmArchVersion => {
                ConfigPropertyValue::Choice(self.arm_arch_version.as_str())
            }
            ConfigPropertyId::ArmVfpV2 => ConfigPropertyValue::Boolean(self.arm_vfp_v2),
            ConfigPropertyId::ArmUnifiedSyntax => {
                ConfigPropertyValue::Boolean(self.arm_unified_syntax)
            }
            ConfigPropertyId::ArmAvRegisters => {
                ConfigPropertyValue::Boolean(self.arm_av_registers)
            }
            ConfigPropertyId::ArmR9Usage => {
                ConfigPropertyValue::Choice(self.arm_r9_usage.as_str())
            }
            ConfigPropertyId::ArmSlUsage => {
                ConfigPropertyValue::Boolean(self.arm_sl_usage)
            }
            ConfigPropertyId::ArmFpUsage => {
                ConfigPropertyValue::Boolean(self.arm_fp_usage)
            }
            ConfigPropertyId::ArmIpUsage => {
                ConfigPropertyValue::Boolean(self.arm_ip_usage)
            }
            ConfigPropertyId::MipsAbi => {
                ConfigPropertyValue::Choice(self.mips_abi.as_str())
            }
            ConfigPropertyId::MipsInstrCategory => {
                ConfigPropertyValue::Choice(self.mips_instr_category.as_str())
            }
            ConfigPropertyId::MipsRegisterPrefix => {
                ConfigPropertyValue::Boolean(self.mips_register_prefix)
            }
            ConfigPropertyId::MipsProdgSnAsInvertedRegs => {
                ConfigPropertyValue::Boolean(self.mips_prodg_sn_as_inverted_regs)
            }
            ConfigPropertyId::PpcCalculatePoolRelocations => {
                ConfigPropertyValue::Boolean(self.ppc_calculate_pool_relocations)
            }
            ConfigPropertyId::X86Formatter => {
                ConfigPropertyValue::Choice(self.x86_formatter.as_str())
            }
        }
    }
    #[allow(clippy::result_unit_err)]
    pub fn set_property_value(
        &mut self,
        id: ConfigPropertyId,
        value: ConfigPropertyValue,
    ) -> Result<(), ()> {
        match id {
            ConfigPropertyId::FunctionRelocDiffs => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.function_reloc_diffs = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::Demangler => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.demangler = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::AnalyzeDataFlow => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.analyze_data_flow = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ShowDataFlow => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.show_data_flow = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::SpaceBetweenArgs => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.space_between_args = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ShowSymbolSizes => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.show_symbol_sizes = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::CombineDataSections => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.combine_data_sections = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::CombineTextSections => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.combine_text_sections = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::PreferredStringEncoding => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.preferred_string_encoding = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmArchVersion => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.arm_arch_version = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmVfpV2 => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.arm_vfp_v2 = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmUnifiedSyntax => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.arm_unified_syntax = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmAvRegisters => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.arm_av_registers = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmR9Usage => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.arm_r9_usage = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmSlUsage => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.arm_sl_usage = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmFpUsage => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.arm_fp_usage = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmIpUsage => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.arm_ip_usage = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsAbi => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.mips_abi = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsInstrCategory => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.mips_instr_category = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsRegisterPrefix => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.mips_register_prefix = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsProdgSnAsInvertedRegs => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.mips_prodg_sn_as_inverted_regs = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::PpcCalculatePoolRelocations => {
                if let ConfigPropertyValue::Boolean(value) = value {
                    self.ppc_calculate_pool_relocations = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::X86Formatter => {
                if let ConfigPropertyValue::Choice(value) = value {
                    if let Ok(value) = value.parse() {
                        self.x86_formatter = value;
                        Ok(())
                    } else {
                        Err(())
                    }
                } else {
                    Err(())
                }
            }
        }
    }
    #[allow(clippy::result_unit_err)]
    pub fn set_property_value_str(
        &mut self,
        id: ConfigPropertyId,
        value: &str,
    ) -> Result<(), ()> {
        match id {
            ConfigPropertyId::FunctionRelocDiffs => {
                if let Ok(value) = value.parse() {
                    self.function_reloc_diffs = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::Demangler => {
                if let Ok(value) = value.parse() {
                    self.demangler = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::AnalyzeDataFlow => {
                if let Ok(value) = value.parse() {
                    self.analyze_data_flow = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ShowDataFlow => {
                if let Ok(value) = value.parse() {
                    self.show_data_flow = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::SpaceBetweenArgs => {
                if let Ok(value) = value.parse() {
                    self.space_between_args = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ShowSymbolSizes => {
                if let Ok(value) = value.parse() {
                    self.show_symbol_sizes = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::CombineDataSections => {
                if let Ok(value) = value.parse() {
                    self.combine_data_sections = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::CombineTextSections => {
                if let Ok(value) = value.parse() {
                    self.combine_text_sections = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::PreferredStringEncoding => {
                if let Ok(value) = value.parse() {
                    self.preferred_string_encoding = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmArchVersion => {
                if let Ok(value) = value.parse() {
                    self.arm_arch_version = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmVfpV2 => {
                if let Ok(value) = value.parse() {
                    self.arm_vfp_v2 = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmUnifiedSyntax => {
                if let Ok(value) = value.parse() {
                    self.arm_unified_syntax = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmAvRegisters => {
                if let Ok(value) = value.parse() {
                    self.arm_av_registers = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmR9Usage => {
                if let Ok(value) = value.parse() {
                    self.arm_r9_usage = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmSlUsage => {
                if let Ok(value) = value.parse() {
                    self.arm_sl_usage = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmFpUsage => {
                if let Ok(value) = value.parse() {
                    self.arm_fp_usage = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::ArmIpUsage => {
                if let Ok(value) = value.parse() {
                    self.arm_ip_usage = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsAbi => {
                if let Ok(value) = value.parse() {
                    self.mips_abi = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsInstrCategory => {
                if let Ok(value) = value.parse() {
                    self.mips_instr_category = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsRegisterPrefix => {
                if let Ok(value) = value.parse() {
                    self.mips_register_prefix = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::MipsProdgSnAsInvertedRegs => {
                if let Ok(value) = value.parse() {
                    self.mips_prodg_sn_as_inverted_regs = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::PpcCalculatePoolRelocations => {
                if let Ok(value) = value.parse() {
                    self.ppc_calculate_pool_relocations = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
            ConfigPropertyId::X86Formatter => {
                if let Ok(value) = value.parse() {
                    self.x86_formatter = value;
                    Ok(())
                } else {
                    Err(())
                }
            }
        }
    }
}
