interoptopus_backend_c 0.14.25

Generates C bindings.
Documentation
use heck::{ToLowerCamelCase, ToShoutySnakeCase, ToSnakeCase, ToUpperCamelCase};

/// Style of indentation used in generated C code
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CFunctionStyle {
    Typedefs,
    ForwardDeclarations,
}

/// Style of indentation used in generated C code
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CIndentationStyle {
    /// Braces on their own lines, not indented
    Allman,
    /// Opening brace on same line as declaration, closing brace on own line, not intended
    KAndR,
    /// Braces on their own lines, intended by two spaces
    GNU,
    /// Braces on their own lines, intended level with members
    Whitesmiths,
}

/// Style of documentation in generated C code
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CNamingStyle {
    /// Names all in lowercase without spacing e.g. 'thetypename'
    Lowercase,
    /// Names all in uppercase without spacing e.g. 'THETYPENAME'
    Uppercase,
    /// Names in mixed case starting with lowercase without spacing e.g. 'theTypeName'
    LowerCamelCase,
    /// Names in mixed case starting with uppercase without spacing e.g. 'TheTypeName'
    UpperCamelCase,
    /// Names in lower case with '_' as spacing e.g. 'the_type_name'
    SnakeCase,
    /// Names in upper case with '_' as spacing e.g. 'THE_TYPE_NAME'
    ShoutySnakeCase,
}

pub(crate) trait ToNamingStyle {
    fn to_naming_style(&self, style: &CNamingStyle) -> String;
}

impl ToNamingStyle for String {
    fn to_naming_style(&self, style: &CNamingStyle) -> String {
        self.as_str().to_naming_style(style)
    }
}

impl ToNamingStyle for &str {
    fn to_naming_style(&self, style: &CNamingStyle) -> String {
        match style {
            CNamingStyle::Lowercase => self.to_lowercase(),
            CNamingStyle::Uppercase => self.to_uppercase(),
            CNamingStyle::LowerCamelCase => self.to_lower_camel_case(),
            CNamingStyle::UpperCamelCase => self.to_upper_camel_case(),
            CNamingStyle::SnakeCase => self.to_snake_case(),
            CNamingStyle::ShoutySnakeCase => self.to_shouty_snake_case(),
        }
    }
}

/// Style of documentation in generated C code
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CDocumentationStyle {
    // No documentation comments are added to header file
    None,
    // Documentation is added inline above relevant declaration
    Inline,
}

/// Configures C code generation.
#[derive(Clone, Debug)]
pub struct Config {
    /// Whether to write conditional directives like `#ifndef _X`.
    pub directives: bool,
    /// Whether to write `#include <>` directives.
    pub imports: bool,
    /// Additional `#include` lines in the form of `<item.h>`` or `"item.h"`.
    pub additional_includes: Vec<String>,
    /// The `_X` in `#ifndef _X` to be used.
    pub ifndef: String,
    /// Multiline string with custom `#define` values.
    pub custom_defines: String,
    /// Prefix to be applied to any function, e.g., `__DLLATTR`.
    pub function_attribute: String,
    /// Comment at the very beginning of the file, e.g., `// (c) My Company.`
    pub file_header_comment: String,
    /// How to prefix everything, e.g., `my_company_`, will be capitalized for constants.
    pub prefix: String,
    /// How to indent code
    pub indentation: CIndentationStyle,
    /// How to add code documentation
    pub documentation: CDocumentationStyle,
    /// How to convert type names
    pub type_naming: CNamingStyle,
    /// How to convert enum variant names
    pub enum_variant_naming: CNamingStyle,
    /// How to convert const names
    pub const_naming: CNamingStyle,
    /// How to convert function parameter names
    pub function_parameter_naming: CNamingStyle,
    /// How to emit functions
    pub function_style: CFunctionStyle,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            directives: true,
            imports: true,
            additional_includes: vec![],
            file_header_comment: "// Automatically generated by Interoptopus.".to_string(),
            ifndef: "interoptopus_generated".to_string(),
            custom_defines: "".to_string(),
            function_attribute: "".to_string(),
            prefix: "".to_string(),
            indentation: CIndentationStyle::Whitesmiths,
            documentation: CDocumentationStyle::Inline,
            type_naming: CNamingStyle::Lowercase,
            enum_variant_naming: CNamingStyle::Uppercase,
            const_naming: CNamingStyle::Uppercase,
            function_parameter_naming: CNamingStyle::Lowercase,
            function_style: CFunctionStyle::ForwardDeclarations,
        }
    }
}