# API Reference
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Command-Line Interface](#command-line-interface)
- [Synopsis](#synopsis)
- [Options](#options)
- [`-o, --output <file>`](#-o-output)
- [`--output-dir <dir>`](#-output-dir)
- [`--lang <language>`](#-lang)
- [`--c`](#-c)
- [`--check-imports`](#-check-imports)
- [`--crate-imports`](#-crate-imports)
- [`--super-imports`](#-super-imports)
- [`--module-prefix <prefix>`](#-module-prefix)
- [`--use-core`](#-use-core)
- [`--header-path <path>`](#-header-path)
- [`--with-helpers`](#-with-helpers)
- [`--arena`](#-arena)
- [`--impl <header>`](#-impl)
- [`--emit <artifacts>`](#-emit)
- [`--cmake`](#-cmake)
- [`--meson`](#-meson)
- [`--shared`](#-shared)
- [`--synta-root <dir>`](#-synta-root)
- [Examples](#examples)
- [Library API -- Rust generation](#library-api-rust-generation)
- [`parse`](#parse)
- [`generate`](#generate)
- [`generate_with_config`](#generatewithconfig)
- [`CodeGenConfig`](#codegenconfig)
- [`StringTypeMode`](#stringtypemode)
- [`DeriveMode`](#derivemode)
- [Library API -- C generation](#library-api-c-generation)
- [`generate_c`](#generate_c)
- [`generate_c_with_config`](#generatecwith_config)
- [`CCodeGenConfig`](#ccodegenconfig)
- [`generate_c_impl`](#generatecimpl)
- [`CImplConfig`](#cimplconfig)
- [AST types](#ast-types)
- [`Module`](#module)
- [`Definition`](#definition)
- [`ParseError`](#parseerror)
- [See Also](#see-also)
Complete reference for the synta-codegen library and command-line interface.
---
## Command-Line Interface
### Synopsis
```
synta-codegen [OPTIONS] <input.asn1> [extra.asn1 ...]
```
### Options
#### `-o, --output <file>`
Write output to `file`. Default: stdout.
#### `--output-dir <dir>`
Write one generated file per input module into `dir`. Files are written in
topological dependency order (base modules first). Cannot be combined with `-o`.
#### `--lang <language>`
Target language. Accepted values: `rust` (default), `c`.
#### `--c`
Shorthand for `--lang c`.
#### `--check-imports`
Parse all input files and check for circular module import cycles. If a cycle is
detected, report it and exit with a non-zero status. No code is generated.
#### `--crate-imports`
Rust only. Emit `use crate::module::Type` statements for imported ASN.1 types.
#### `--super-imports`
Rust only. Emit `use super::module::Type` statements for imported ASN.1 types.
#### `--module-prefix <prefix>`
Rust only. Emit `use <prefix>::module::Type` statements. The prefix is used
verbatim followed by `::`.
#### `--use-core`
Rust only. Replace `std::` paths with `core::` equivalents in generated code
(no_std environments).
#### `--header-path <path>`
C only. Path written into the `#include "..."` directive for `synta.h` in the
generated header. Default: `"synta.h"`.
#### `--with-helpers`
C only. Generate `_init`, `_validate`, and `_print` inline helper functions for
every type.
#### `--arena`
C only. Generate the `SyntaArena` type and `_decode_arena()` function prototypes
(in the header) or bodies (in the implementation).
#### `--impl <header>`
C only. Single-file mode: generate a `.c` implementation file instead of a `.h`
header file. The argument specifies the name of the corresponding header file,
which is placed in the generated `#include "..."` directive. Not compatible with
`--output-dir` and multiple input files; use `--emit` instead.
#### `--emit <artifacts>`
C only. Used with `--output-dir`. Controls which artifacts are written per
module. Accepted values:
- `header` (default) — write only `.h` header files.
- `impl` — write only `.c` implementation files.
- `both` — write both `.h` and `.c` files for each module.
When `--cmake` or `--meson` is combined with `--output-dir`, `--emit` defaults
to `both` automatically so the generated build file's source references are
satisfied.
#### `--cmake`
Generate a `CMakeLists.txt` build file. Without `--output-dir`, writes only the
build file (to stdout or `-o`). With `--output-dir`, also generates C source
files (equivalent to `--emit both`) so the build file's `.c` references are
immediately satisfied.
#### `--meson`
Generate a `meson.build` file. Without `--output-dir`, writes only the build
file (to stdout or `-o`). With `--output-dir`, also generates C source files
(equivalent to `--emit both`).
#### `--shared`
Used with `--cmake` or `--meson`. Configure the generated build file to build a
shared library instead of a static library.
#### `--synta-root <dir>`
Used with `--cmake` or `--meson`. Embed `dir` as the hard-coded path to the synta
installation in the generated build file.
### Examples
**Rust: single file**
```sh
synta-codegen schema.asn1 -o src/generated.rs
synta-codegen schema.asn1 --crate-imports -o src/generated.rs
synta-codegen schema.asn1 --super-imports -o src/generated.rs
synta-codegen schema.asn1 --module-prefix my_lib -o src/generated.rs
synta-codegen schema.asn1 --use-core -o src/generated.rs
**Rust: multi-file output**
```sh
synta-codegen base.asn1 user.asn1 --crate-imports --output-dir src/gen/
synta-codegen base.asn1 user.asn1 --check-imports
```
**C: header and implementation**
```sh
synta-codegen schema.asn1 --c -o generated.h
synta-codegen schema.asn1 --impl generated.h -o generated.c
synta-codegen schema.asn1 --c --with-helpers -o generated.h
synta-codegen schema.asn1 --c --arena -o generated.h
synta-codegen schema.asn1 --impl generated.h --arena -o generated.c
synta-codegen schema.asn1 --c --header-path "../../include/synta.h" -o generated.h
```
**C: multi-file output**
```sh
synta-codegen base.asn1 user.asn1 --c --output-dir ./generated/
synta-codegen base.asn1 user.asn1 --c --emit both --output-dir ./generated/
synta-codegen base.asn1 user.asn1 --check-imports
```
**Build system files**
```sh
synta-codegen schema.asn1 --cmake -o CMakeLists.txt
synta-codegen schema.asn1 --meson -o meson.build
synta-codegen base.asn1 user.asn1 --cmake --output-dir ./generated/
synta-codegen schema.asn1 --cmake --synta-root /opt/synta -o CMakeLists.txt
synta-codegen schema.asn1 --cmake --shared -o CMakeLists.txt
```
---
## Library API -- Rust generation
### `parse`
```rust
pub fn parse(input: &str) -> Result<Module, ParseError>
```
Parse an ASN.1 module definition from `input`. Returns the parsed AST on success
or a `ParseError` with line and column information on failure. Accepts exactly one
module per call.
### `generate`
```rust
pub fn generate(module: &Module) -> Result<String, std::fmt::Error>
```
Generate Rust source code for `module` using default configuration: no import
statements emitted, `std::` paths used.
### `generate_with_config`
```rust
pub fn generate_with_config(
module: &Module,
config: CodeGenConfig,
) -> Result<String, std::fmt::Error>
```
Generate Rust source code applying the settings in `config`.
### `CodeGenConfig`
```rust
pub struct CodeGenConfig {
pub module_path_prefix: Option<String>,
pub use_core: bool,
pub skip_imported_types: std::collections::HashSet<String>,
pub imported_type_lifetimes: std::collections::HashMap<String, String>,
pub string_type_mode: StringTypeMode,
pub any_as_raw_der: bool,
pub derive_mode: DeriveMode,
}
```
- `module_path_prefix` -- when `Some(prefix)`, emit `use prefix::module::Type` for ASN.1 IMPORTS; `None` annotates imports as comments only.
- `use_core` -- when `true`, emits `core::` instead of `std::` in generated paths.
- `skip_imported_types` -- set of imported type names not declared locally (assumed to come from external modules).
- `imported_type_lifetimes` -- map from imported type name to lifetime string (e.g. `"'a"`) for zero-copy types.
- `string_type_mode` -- controls whether `OCTET STRING`, `BIT STRING`, and string types emit owned or zero-copy borrowed forms. See [`StringTypeMode`](#stringtypemode).
- `any_as_raw_der` -- when `true`, `ANY` and `ANY DEFINED BY` fields are emitted as `RawDer<'a>` instead of `Element<'a>`.
- `derive_mode` -- controls how derive macros are gated. See [`DeriveMode`](#derivemode).
Convenience constructors set `module_path_prefix` and leave all other fields at their defaults:
```rust
use synta_codegen::CodeGenConfig;
let config = CodeGenConfig::with_crate_imports(); // use crate::module::Type
let config = CodeGenConfig::with_super_imports(); // use super::module::Type
let config = CodeGenConfig::with_custom_prefix("my_lib"); // use my_lib::module::Type
```
### `StringTypeMode`
```rust
pub enum StringTypeMode {
Owned, // default
Borrowed,
}
```
- `Owned` -- emit heap-allocating owned types (`OctetString`, `BitString`, `Utf8String`, etc.). Default.
- `Borrowed` -- emit zero-copy borrowed types (`OctetStringRef<'a>`, `BitStringRef<'a>`, `Utf8StringRef<'a>`, etc.).
### `DeriveMode`
```rust
pub enum DeriveMode {
FeatureGated, // default
Always,
Custom(String),
}
```
Controls how derive macros (`Asn1Sequence`, `Asn1Choice`, `Asn1Set`) and their helper
attributes are emitted.
- `FeatureGated` (default) -- wraps every annotation in `#[cfg_attr(feature = "derive", …)]`. The consuming crate must declare `[features] derive = ["dep:synta-derive"]` in its `Cargo.toml`.
- `Always` -- emits `#[derive(Asn1Sequence)]` unconditionally with no feature gate. Use this when the consuming crate always depends on `synta-derive`.
- `Custom(name)` -- uses a caller-supplied feature name instead of `"derive"`.
**Example:**
```rust
use synta_codegen::{CodeGenConfig, DeriveMode};
// Default: feature-gated (consuming crate needs a "derive" feature)
let config = CodeGenConfig::default();
// Always emit derive attributes unconditionally
let config = CodeGenConfig {
derive_mode: DeriveMode::Always,
..CodeGenConfig::with_crate_imports()
};
// Use a custom feature name
let config = CodeGenConfig {
derive_mode: DeriveMode::Custom("asn1-derive".to_string()),
..CodeGenConfig::with_crate_imports()
};
```
---
## Library API -- C generation
### `generate_c`
```rust
pub fn generate_c(module: &Module) -> Result<String, Box<dyn std::error::Error>>
```
Generate a C header file from `module` using default configuration.
### `generate_c_with_config`
```rust
pub fn generate_c_with_config(
module: &Module,
config: CCodeGenConfig,
) -> Result<String, Box<dyn std::error::Error>>
```
Generate a C header file applying the settings in `config`.
### `CCodeGenConfig`
```rust
pub struct CCodeGenConfig {
pub synta_header_path: Option<String>,
pub generate_helpers: bool,
pub arena_mode: bool,
}
```
- `synta_header_path` -- path placed in `#include "..."` for `synta.h`. Default: `"synta.h"`.
- `generate_helpers` -- emit `_init`, `_validate`, and `_print` inline helpers. Default: `false`.
- `arena_mode` -- emit `SyntaArena` type and `_decode_arena()` prototypes. Default: `false`.
Builder methods are available for convenience:
```rust,ignore
// Set custom synta.h include path
CCodeGenConfig::with_header_path("../../include/synta.h")
// Enable _init / _validate / _print helpers
config.with_helpers()
// Enable SyntaArena + _decode_arena() prototypes
config.with_arena()
```
**Example:**
```rust,ignore
use synta_codegen::{parse, generate_c_with_config, CCodeGenConfig};
let module = parse(schema)?;
let config = CCodeGenConfig::with_header_path("synta/synta.h")
.with_helpers()
.with_arena();
let header = generate_c_with_config(&module, config)?;
```
### `generate_c_impl`
```rust
pub fn generate_c_impl(
module: &Module,
config: CImplConfig,
) -> Result<String, Box<dyn std::error::Error>>
```
Generate a C implementation file (`.c`) from `module`.
### `CImplConfig`
```rust
pub struct CImplConfig {
pub header_file: String,
pub arena_mode: bool,
}
```
- `header_file` -- name of the corresponding header file, placed in the generated
`#include "..."` directive.
- `arena_mode` -- generate `_decode_arena()` function bodies. Default: `false`.
**Example:**
```rust
use synta_codegen::{parse, generate_c_impl, CImplConfig};
let module = parse(schema)?;
let impl_code = generate_c_impl(&module, CImplConfig {
header_file: "types.h".into(),
arena_mode: false,
})?;
```
---
## AST types
These types are returned by `parse()` and consumed by the generation functions.
They are part of the public API but are primarily intended for tooling that needs
to inspect the parsed module.
### `Module`
```rust
pub struct Module {
pub name: String,
pub tagging: TaggingMode,
pub imports: Vec<Import>,
pub exports: Vec<String>,
pub definitions: Vec<Definition>,
}
```
### `Definition`
```rust
pub struct Definition {
pub name: String,
pub ty: Type,
}
```
### `ParseError`
```rust
pub struct ParseError {
pub message: String,
pub line: usize,
pub column: usize,
}
```
`ParseError` implements `std::fmt::Display` and `std::error::Error`.
---
## See Also
- [rust-generation.md](rust-generation.md) -- Rust code generation details, build.rs integration, multi-module projects
- [c-generation.md](c-generation.md) -- C code generation details, libcsynta API, multi-module projects
- [asn1-support.md](asn1-support.md) -- supported ASN.1 syntax reference