diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..e69de29 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a38f37e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 +max_line_length = 120 + +[*.md] +# double whitespace at end of line +# denotes a line break in Markdown +trim_trailing_whitespace = false + +[{*.sh,*.yml,*.yaml}] +indent_size = 2 diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..7e81fbc --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,87 @@ +name: Publish + +on: + workflow_dispatch: + push: + tags: + - v* + +env: + CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse + +jobs: + publish: + strategy: + matrix: + triple: + - { os: 'ubuntu-latest', target: 'x86_64-unknown-linux-gnu', lib: 'libcicd_ffi.so' } + - { os: 'macos-latest', target: 'aarch64-apple-darwin', lib: 'libcicd_ffi.dylib' } + - { os: 'macos-latest', target: 'x86_64-apple-darwin', lib: 'libcicd_ffi.dylib' } + - { os: 'windows-latest', target: 'x86_64-pc-windows-msvc', lib: 'cicd_ffi.dll' } + env: + ARTIFACT_FILE_PATH: "./target/${{ matrix.triple.target }}/release/${{ matrix.triple.lib }}" + KOTLIN_BINDINGS_PATH: "./uniffi" + PYTHON_BINDINGS_PATH: "./cicd_ffi.py" + UDL_PATH: "./cicd_ffi/src/cicd_ffi.udl" + ZIP_NAME: "cicd_ffi-${{ matrix.triple.target }}.zip" + name: Publish artifacts for ${{ matrix.triple.os }} with ${{ matrix.triple.target }} + runs-on: ${{ matrix.triple.os }} + + steps: + # Get current tag to use as the release name. + - name: Get current tag + id: tag + run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + + # Get current date to use as the release as part of the release name. + - name: Get current date + id: date + run: echo "date=$(date --rfc-3339=date)" >> $GITHUB_OUTPUT + + - uses: actions/checkout@v3 + with: + submodules: recursive + token: ${{ secrets.PAT }} + fetch-depth: 1 + + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: "${{ matrix.triple.target }}" + + - name: Generate Cargo.lock + run: cargo update + + - name: Cache dependencies + uses: actions/cache/restore@v3 + with: + path: | + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ./target + key: "${{ runner.os }}-rust-${{ matrix.triple.target }}-${{ hashFiles('**/Cargo.lock') }}" + restore-keys: "${{ runner.os }}-rust-${{ matrix.triple.target }}-" + + - name: Build project + run: cargo build --release --target ${{ matrix.triple.target }} + + - name: Build kotlin artifacts + run: cargo run --release --bin uniffi-bindgen generate ${{ env.UDL_PATH }} -l kotlin -o ./ --no-format + + - name: Build python artifacts + run: cargo run --release --bin uniffi-bindgen generate ${{ env.UDL_PATH }} -l python -o ./ --no-format + + - name: Zip artifacts + run: 7z a ${{ env.ZIP_NAME }} ${{ env.KOTLIN_BINDINGS_PATH }} ${{ env.PYTHON_BINDINGS_PATH }} ${{ env.ARTIFACT_FILE_PATH }} + + - name: Upload development binaries to release + uses: svenstaro/upload-release-action@v2 + with: + release_name: "[${{ steps.tag.outputs.tag }}] - ${{ steps.date.outputs.date }}" + repo_token: ${{ secrets.PAT }} + file: ${{ env.ZIP_NAME }} + asset_name: ${{ env.ZIP_NAME }} + tag: ${{ github.ref }} diff --git a/.github/workflows/update_caches.yaml b/.github/workflows/update_caches.yaml new file mode 100644 index 0000000..e709cca --- /dev/null +++ b/.github/workflows/update_caches.yaml @@ -0,0 +1,143 @@ +name: Update caches + +on: + ## Run on every push to the dev branch. + push: + branches: + - master + ## Run every Wednesday and Sunday at 00:00 UTC. + schedule: + - cron: "0 0 * * 0,3" + ## Manual trigger. + workflow_dispatch: + +jobs: + cache-ubuntu: + strategy: + matrix: + triple: + # x86_64 architecture with the Linux GNU toolchain. + - { os: 'ubuntu-latest', target: 'x86_64-unknown-linux-gnu' } + + name: Update Rust stable caches for ${{ matrix.triple.os }} with ${{ matrix.triple.target }} + runs-on: ${{ matrix.triple.os }} + steps: + # Checkout the repository and all its submodules, only with the latest commit. + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + token: ${{ secrets.PAT }} + fetch-depth: 1 + + # Install Rust stable. + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: "${{ matrix.triple.target }}" + + # Generate the Cargo.lock file. Since we ignore the lockfile on .gitignore, we need to generate it before we can check the cache. + - name: Generate Cargo.lock + run: cargo update + + # Check if a cache exists for the given configuration. + - name: Check cache + id: cache + uses: actions/cache/restore@v3 + with: + path: | + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ./target + key: "${{ runner.os }}-rust-${{ matrix.triple.target }}-${{ hashFiles('**/Cargo.lock') }}" + lookup-only: true + + # Build the project if cache not found. + - name: Build project + if: steps.cache.outputs.cache-hit != 'true' + run: cargo build --workspace --release --target ${{ matrix.triple.target }} + + # Save the cache if not found. + - name: Save cache + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: | + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ./target + key: "${{ runner.os }}-rust-${{ matrix.triple.target }}-${{ hashFiles('**/Cargo.lock') }}" + + # Since only Ubuntu is used for testing in a daily basis, we only need to cache the other platforms once in a while, for publishing. + cache-non-ubuntu: + strategy: + matrix: + triple: + # ARM64 (Apple Silicon) architecture for macOS. + - { os: 'macos-latest', target: 'aarch64-apple-darwin' } + # x86_64 architecture for macOS. + - { os: 'macos-latest', target: 'x86_64-apple-darwin' } + # x86_64 architecture for Windows using MSVC (Microsoft Visual C++). + - { os: 'windows-latest', target: 'x86_64-pc-windows-msvc' } + + name: Update Rust stable caches for ${{ matrix.triple.os }} with ${{ matrix.triple.target }} + runs-on: ${{ matrix.triple.os }} + # if: ${{ github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' }} + steps: + # Checkout the repository and all its submodules, only with the latest commit. + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + token: ${{ secrets.PAT }} + fetch-depth: 1 + + # Install Rust stable. + - name: Install Rust stable + uses: dtolnay/rust-toolchain@stable + with: + targets: "${{ matrix.triple.target }}" + + # Generate the Cargo.lock file. Since we ignore the lockfile on .gitignore, we need to generate it before we can check the cache. + - name: Generate Cargo.lock + run: cargo update + + # Check if a cache exists for the given configuration. + - name: Check cache + id: cache + uses: actions/cache/restore@v3 + with: + path: | + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ./target + key: "${{ runner.os }}-rust-${{ matrix.triple.target }}-${{ hashFiles('**/Cargo.lock') }}" + lookup-only: true + + # Build the project if cache not found. + - name: Build project + if: steps.cache.outputs.cache-hit != 'true' + run: cargo build --workspace --release --target ${{ matrix.triple.target }} + + # Save the cache if not found. + - name: Save cache + if: steps.cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v3 + with: + path: | + ~/.cargo/.crates.toml + ~/.cargo/.crates2.json + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ./target + key: "${{ runner.os }}-rust-${{ matrix.triple.target }}-${{ hashFiles('**/Cargo.lock') }}" diff --git a/.gitignore b/.gitignore index 6985cf1..ebbcab6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,7 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + +# IntelliJ IDEA +.idea/ +*.iml diff --git a/.rustc_info.json b/.rustc_info.json new file mode 100644 index 0000000..80316d2 --- /dev/null +++ b/.rustc_info.json @@ -0,0 +1 @@ +{"rustc_fingerprint":8006516878952857912,"outputs":{"4614504638168534921":{"success":true,"status":"","code":0,"stdout":"rustc 1.71.0 (8ede3aae2 2023-07-12)\nbinary: rustc\ncommit-hash: 8ede3aae28fe6e4d52b38157d7bfe0d3bceef225\ncommit-date: 2023-07-12\nhost: x86_64-pc-windows-msvc\nrelease: 1.71.0\nLLVM version: 16.0.5\n","stderr":""},"15729799797837862367":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Augusto\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""},"12744816824612481171":{"success":true,"status":"","code":0,"stdout":"___.exe\nlib___.rlib\n___.dll\n___.dll\n___.lib\n___.dll\nC:\\Users\\Augusto\\.rustup\\toolchains\\stable-x86_64-pc-windows-msvc\npacked\n___\ndebug_assertions\npanic=\"unwind\"\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"msvc\"\ntarget_family=\"windows\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"windows\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"pc\"\nwindows\n","stderr":""}},"successes":{}} \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f0a0c22 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] + +members = [ + "cicd_ffi", + "cicd_tests", +] diff --git a/cicd_ffi/Cargo.toml b/cicd_ffi/Cargo.toml new file mode 100644 index 0000000..b117d56 --- /dev/null +++ b/cicd_ffi/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "cicd_ffi" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[[bin]] +name = "uniffi-bindgen" +path = "./src/uniffi-bindgen.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +crate-type = ["cdylib"] +name = "cicd_ffi" + +[dependencies] +cicd_tests = { path = "../cicd_tests" } +uniffi = { version = "0.24.1", features = ["cli"] } + +[build-dependencies] +uniffi = { version = "0.24.1", features = ["build"] } diff --git a/cicd_ffi/build.rs b/cicd_ffi/build.rs new file mode 100644 index 0000000..9a4645a --- /dev/null +++ b/cicd_ffi/build.rs @@ -0,0 +1 @@ +fn main() { uniffi::generate_scaffolding("./src/cicd_ffi.udl",).unwrap(); } diff --git a/cicd_ffi/src/cicd_ffi.udl b/cicd_ffi/src/cicd_ffi.udl new file mode 100644 index 0000000..c34b224 --- /dev/null +++ b/cicd_ffi/src/cicd_ffi.udl @@ -0,0 +1,20 @@ +namespace cicd_ffi { + + +}; + +[Enum] +interface SchemaName { + Name(string name); + Authorization(string authorization); + SchemaNameAndAuthorization(string name, string authorization); +}; + +interface CreateSchema { + constructor(boolean if_not_exists, SchemaName schema_name); + + boolean if_not_exists(); + + + SchemaName schema_name(); +}; diff --git a/cicd_ffi/src/lib.rs b/cicd_ffi/src/lib.rs new file mode 100644 index 0000000..8161437 --- /dev/null +++ b/cicd_ffi/src/lib.rs @@ -0,0 +1,6 @@ +pub use cicd_tests::create_schema::{ + CreateSchema, + SchemaName, +}; + +uniffi::include_scaffolding!("cicd_ffi"); diff --git a/cicd_ffi/src/uniffi-bindgen.rs b/cicd_ffi/src/uniffi-bindgen.rs new file mode 100644 index 0000000..f6cff6c --- /dev/null +++ b/cicd_ffi/src/uniffi-bindgen.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi::uniffi_bindgen_main() +} diff --git a/cicd_tests/Cargo.toml b/cicd_tests/Cargo.toml new file mode 100644 index 0000000..2d67d41 --- /dev/null +++ b/cicd_tests/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "cicd_tests" +version = "0.1.0" +edition = "2021" + +[dependencies] +serde = { version = "1.0.96", features = ["derive"] } +serde_json = "1.0.96" +anyhow = "1.0.71" diff --git a/cicd_tests/src/create_schema.rs b/cicd_tests/src/create_schema.rs new file mode 100644 index 0000000..e7f36ca --- /dev/null +++ b/cicd_tests/src/create_schema.rs @@ -0,0 +1,85 @@ +use std::fmt; + +/// `Postgresql` `CREATE SCHEMA` statement. +/// +/// Check the [`Postgresql documentation`] for more information. +/// +/// [`Postgresql documentation`]: https://www.postgresql.org/docs/14/sql-createschema.html + +pub struct CreateSchema { + if_not_exists: bool, + schema_name: SchemaName, +} + +/// SchemaName is a wrapper for a schema name and an authorization name. +#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug,)] + +pub enum SchemaName { + /// Only the schema name is specified. + Name { name: String, }, + /// Only the schema authorization is specified. + Authorization { authorization: String, }, + /// Both the schema name and authorization are specified. + SchemaNameAndAuthorization { + name: String, + authorization: String, + }, +} + +impl CreateSchema { + pub fn new( + if_not_exists: bool, + schema_name: SchemaName, + ) -> Self { + Self { + if_not_exists, + schema_name, + } + } + + pub fn if_not_exists(&self,) -> bool { self.if_not_exists } + + pub fn schema_name(&self,) -> SchemaName { self.schema_name.clone() } +} + +impl fmt::Display for CreateSchema { + fn fmt( + &self, + f: &mut fmt::Formatter, + ) -> fmt::Result { + write!( + f, + "CREATE SCHEMA {if_not_exists}{schema_name}", + if_not_exists = if self.if_not_exists { + "IF NOT EXISTS " + } else { + "" + }, + schema_name = self.schema_name, + ) + } +} + +impl fmt::Display for SchemaName { + fn fmt( + &self, + f: &mut fmt::Formatter, + ) -> fmt::Result { + match self { + SchemaName::Name { + name, + } => write!(f, "{name}"), + SchemaName::Authorization { + authorization, + } => { + write!(f, "AUTHORIZATION {authorization}") + }, + SchemaName::SchemaNameAndAuthorization { + name, + authorization, + } => { + write!(f, "{name} AUTHORIZATION {authorization}") + }, + } + } +} diff --git a/cicd_tests/src/lib.rs b/cicd_tests/src/lib.rs new file mode 100644 index 0000000..934b8ca --- /dev/null +++ b/cicd_tests/src/lib.rs @@ -0,0 +1 @@ +pub mod create_schema; diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..f5d7999 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,281 @@ +# Maximum width of an array literal before falling back to vertical formatting. +# Default: 60 +array_width = 100 + +# Maximum width of the args of a function-like attributes before falling back to vertical formatting. +# Default: 70 +attr_fn_like_width = 100 + +# Where to put a binary operator when a binary expression goes multiline. +# Default: "Front" +binop_separator = "Front" + +# Minimum number of blank lines which must be put between items. +# Default: 0 +blank_lines_lower_bound = 0 + +# Maximum number of blank lines which can be put between items. +# Default: 1 +blank_lines_upper_bound = 1 + +# Brace style for items. +# Default: "SameLineWhere" +brace_style = "SameLineWhere" + +# Maximum width of a chain to fit on one line. +# Default: 60 +chain_width = 100 + +# Whether to use colored output or not. +# Default: "Auto" +color = "Always" + +# Combine control expressions with function calls. +# Default: true +combine_control_expr = true + +# Maximum length of comments. No effect unless wrap_comments = true. +# Default: 80 +comment_width = 100 + +# Replace strings of _ wildcards by a single .. in tuple patterns. +# Default: false +condense_wildcard_suffixes = true + +# Brace style for control flow constructs. +# Default: "AlwaysSameLine" +control_brace_style = "AlwaysSameLine" + +# Don't reformat anything. +# Default: false +disable_all_formatting = false + +# Specifies which edition is used by the parser. +# Default: "2015" +edition = "2021" + +# Put empty-body functions and impls on a single line. +# Default: true +empty_item_single_line = true + +# The maximum length of enum variant having discriminant, that gets vertically aligned with others. +# Default: 0 +enum_discrim_align_threshold = 0 + +# Error if Rustfmt is unable to get all lines within max_width, except for comments and string literals. +# Default: false +error_on_line_overflow = false + +# Error if unable to get comments or string literals within max_width, or they are left with trailing whitespaces. +# Default: false +error_on_unformatted = false + +# Maximum width of the args of a function call before falling back to vertical formatting. +# Default: 60 +fn_call_width = 100 + +# Control the layout of parameters in function signatures. +# Default: "Tall" +fn_params_layout = "Vertical" + +# Put single-expression functions on a single line. +# Default: false +fn_single_line = true + +# Always print the abi for extern items. +# Default: true +force_explicit_abi = true + +# Force multiline closure and match arm bodies to be wrapped in a block. +# Default: false +force_multiline_blocks = true + +# Format code snippet included in doc comments. +# Default: false +format_code_in_doc_comments = true + +# Max width for code snippets included in doc comments. Only used if format_code_in_doc_comments is true. +# Default: 100 +doc_comment_code_block_width = 100 + +# Format generated files. A file is considered generated if any of the first five lines contain a @generated comment marker. +# Default: true +format_generated_files = true + +# Format the metavariable matching patterns in macros. +# Default: false +format_macro_matchers = true + +# Format the bodies of macros. +# Default: true +format_macro_bodies = true + +# Skip formatting the bodies of macro invocations with the following names. +# Default: [] +skip_macro_invocations = [] + +# Format string literals where necessary. +# Default: false +format_strings = false + +# Use tab characters for indentation, spaces for alignment. +# Default: false +hard_tabs = false + +# Control the case of the letters in hexadecimal literal values. +# Default: "Preserve" +hex_literal_case = "Upper" + +# Do not show parse errors if the parser failed to parse files. +# Default: false +hide_parse_errors = false + +# Indent style of imports. +# Default: "Block" +imports_indent = "Block" + +# Item layout inside a imports block. +# Default: "Mixed" +imports_layout = "Vertical" + +# Indent on expressions or items. +# Default: "Block" +indent_style = "Block" + +# Write an item and its attribute on the same line if their combined width is below a threshold. +# Default: 0 +inline_attribute_width = 0 + +# Controls whether arm bodies are wrapped in cases where the first line of the body cannot fit on the same line as the => operator. +# Default: true +match_arm_blocks = true + +# Controls whether to include a leading pipe on match arms. +# Default: "Never" +match_arm_leading_pipes = "Never" + +# Put a trailing comma after a block based match arm (non-block arms are not affected). +# Default: false +match_block_trailing_comma = true + +# Maximum width of each line. +# Default: 100 +max_width = 100 + +# Merge multiple derives into a single one. +# Default: true +merge_derives = true + +# Controls how imports are structured in use statements. Imports will be merged or split to the configured level of granularity. +# Default: "Preserve" +imports_granularity = "Crate" + +# Unix or Windows line endings. +# Default: "Auto" +newline_style = "Unix" + +# Convert /* */ comments to // comments where possible. +# Default: false +normalize_comments = true + +# Convert #![doc] and #[doc] attributes to //! and /// doc comments. +# Default: false +normalize_doc_attributes = true + +# When structs, slices, arrays, and block/array-like macros are used as the last argument in an expression list, allow +# them to overflow (like blocks/closures) instead of being indented on a new line. +# Default: false +overflow_delimited_expr = false + +# Remove nested parens. +# Default: true +remove_nested_parens = true + +# Reorder impl items. type and const are put first, then macros and methods. +# Default: true +reorder_impl_items = true + +# Reorder import and extern crate statements alphabetically in groups (a group is separated by a newline). +# Default: true +reorder_imports = true + +# Controls the strategy for how consecutive imports are grouped together. +# Default: "StdExternalCrate" +group_imports = "StdExternalCrate" + +# Reorder mod declarations alphabetically in group. +# Default: true +reorder_modules = true + +# The width threshold for an array element to be considered "short". +# Default: 10 +short_array_element_width_threshold = 0 + +# Don't reformat out of line modules. +# Default: false +skip_children = false + +# Maximum line length for single line if-else expressions. +# Default: 50 +single_line_if_else_max_width = 0 + +# Maximum line length for single line let-else statements. +# Default: 50 +single_line_let_else_max_width = 0 + +# Leave a space after the colon. +# Default: true +space_after_colon = true + +# Leave a space before the colon. +# Default: false +space_before_colon = false + +# Put spaces around the .., ..=, and ... range operators. +# Default: false +spaces_around_ranges = false + +# The maximum diff of width between struct fields to be aligned with each other. +# Default: 0 +struct_field_align_threshold = 30 + +# Put small struct literals on a single line. +# Default: true +struct_lit_single_line = false + +# Maximum width in the body of a struct literal before falling back to vertical formatting. A value of 0 (zero) results +# in struct literals always being broken into multiple lines. Note this occurs when use_small_heuristics is set to Off. +# Default: 18 +struct_lit_width = 0 + +# Maximum width in the body of a struct variant before falling back to vertical formatting. +# Default: 35 +struct_variant_width = 35 + +# Number of spaces per tab. +# Default: 4 +tab_spaces = 4 + +# How to handle trailing commas for lists. +# Default: "Vertical" +trailing_comma = "Always" + +# Add trailing semicolon after break, continue and return. +# Default: true +trailing_semicolon = true + +# Determines if + or = are wrapped in spaces in the punctuation of types. +# Default: "Wide" +type_punctuation_density = "Wide" + +# Use field initialize shorthand if possible. +# Default: false +use_field_init_shorthand = true + +# Replace uses of the try! macro by the ? shorthand. +# Default: false +use_try_shorthand = true + +# Break comments to fit on the line. +# Default: false +wrap_comments = true