# API Reference
Complete reference for the synta-codegen library and command-line interface (Rust generation).
## 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`.
#### `--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`
Emit `use crate::module::Type` statements for imported ASN.1 types.
#### `--super-imports`
Emit `use super::module::Type` statements for imported ASN.1 types.
#### `--module-prefix <prefix>`
Emit `use <prefix>::module::Type` statements. The prefix is used verbatim followed
by `::`.
#### `--use-core`
Replace `std::` paths with `core::` equivalents in generated code (no_std
environments).
### Examples
**Single-file output**
```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
**Multi-file output**
```sh
synta-codegen base.asn1 user.asn1 --crate-imports --output-dir src/gen/
synta-codegen base.asn1 user.asn1 --check-imports
```
---
## Library API
### `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,
pub raw_der_fields: std::collections::HashSet<String>,
}
```
Fields:
- `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).
- `raw_der_fields` — set of field names (after snake_case conversion) that are
always emitted as `RawDer<'a>` regardless of their ASN.1 type; useful for
deferring decoding of expensive fields such as `issuer`, `subject`, `extensions`.
Convenience constructors:
```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 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()
};
```
---
## 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`.
---
## Convenience Traits
These traits are defined in the core `synta` crate and re-exported from its
crate root. They are automatically available on all conforming types — no
additional feature flags are required.
### `ToDer`
```rust
pub trait ToDer: Encode + Sized {
fn to_der(&self) -> Result<Vec<u8>, Error>;
fn to_ber(&self) -> Result<Vec<u8>, Error>;
}
```
Blanket-implemented for every `T: Encode`. Encodes a single value to DER or
BER bytes without constructing an `Encoder` manually.
### `FromDer`
```rust
pub trait FromDer: Sized {
fn from_der(input: &[u8]) -> Result<Self, Error>;
fn from_ber(input: &[u8]) -> Result<Self, Error>;
}
```
Blanket-implemented for every `T: for<'a> Decode<'a>` (owned/static types
only). Decodes a single value from a byte slice without constructing a
`Decoder` manually. Returns `Error::TrailingData` if the input contains bytes
beyond the decoded TLV. Zero-copy borrowed types (e.g. `OctetStringRef<'a>`)
must use `Decoder` directly.
---
## See also
- [codegen/overview.md](codegen/overview.md) — build.rs integration, multi-module projects
- [codegen/type-mappings.md](codegen/type-mappings.md) — ASN.1 to Rust type table
- [asn1/limitations.md](asn1/limitations.md) — supported ASN.1 syntax