synta 0.2.5

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# no_std Support

## Feature levels

Synta provides three feature levels:

### 1. no_std (no alloc)

The most minimal configuration, suitable for the most constrained environments.

```toml
[dependencies]
synta = { version = "0.1", default-features = false }
```

Available:
- Zero-copy tag and length parsing
- Primitive types with stack allocation
- Fixed-size types
- SmallVec optimization for Integer and OID types

Limitations:
- No dynamic memory allocation
- Limited to types that can be decoded without heap allocation
- No indefinite length support
- Error messages are `&'static str`

```rust
#![no_std]

use synta::{Decoder, Encoding};
use synta::types::primitive::Integer;

fn decode_integer(data: &[u8]) -> Result<i64, synta::Error> {
    let mut decoder = Decoder::new(data, Encoding::Der);
    let int: Integer = decoder.decode()?;
    int.as_i64()
}
```

### 2. no_std + alloc

Provides full ASN.1 functionality without requiring std.

```toml
[dependencies]
synta = { version = "0.1", default-features = false, features = ["alloc"] }
```

Additional features beyond no_std:
- Full SEQUENCE, SET, and constructed type support
- Indefinite length support (for BER)
- Vec-based types (SequenceOf, SetOf)
- String types with dynamic allocation

```rust
#![no_std]
extern crate alloc;

use synta::{Decoder, Encoding};
use synta::types::constructed::Sequence;

fn decode_sequence(data: &[u8]) -> Result<Sequence, synta::Error> {
    let mut decoder = Decoder::new(data, Encoding::Der);
    decoder.decode()
}
```

### 3. std (default)

Full standard library support.

```toml
[dependencies]
synta = "0.1"  # std is default
```

## Feature comparison

| Feature | no_std | no_std+alloc | std |
|---------|--------|--------------|-----|
| Tag/Length parsing | yes | yes | yes |
| Primitive types | yes | yes | yes |
| SmallVec optimization | yes | yes | yes |
| SEQUENCE/SET | no | yes | yes |
| SequenceOf/SetOf | no | yes | yes |
| String types | limited | yes | yes |
| Indefinite length | no | yes | yes |
| Derive macros | no | no | yes |
| Detailed errors | no | no | yes |
| std::error::Error | no | no | yes |

## Derive macro support

Derive macros require proc-macros, which need std at compile time.  The `derive`
feature is only available when `std` is enabled.

For derive-like functionality in no_std environments, manually implement the
`Encode`, `Decode`, and `Tagged` traits following the patterns in the library.

## Code generation for no_std

The `--use-core` CLI flag replaces `std::` paths with `core::` equivalents:

```sh
synta-codegen schema.asn1 --use-core -o src/generated.rs
```

Generated code uses `core::convert::TryFrom` instead of `std::convert::TryFrom`.
This is compatible with the no_std configuration.

In `CodeGenConfig`:

```rust
use synta_codegen::CodeGenConfig;

let config = CodeGenConfig {
    use_core: true,
    ..Default::default()
};
```

## Building for embedded targets

```bash
# Install target
rustup target add thumbv7em-none-eabihf

# Build for no_std (no alloc)
cargo build --target thumbv7em-none-eabihf --no-default-features

# Build for no_std + alloc
cargo build --target thumbv7em-none-eabihf --no-default-features --features alloc
```

Common targets:
- ARM Cortex-M: `thumbv7em-none-eabihf`, `thumbv6m-none-eabi`
- RISC-V: `riscv32imac-unknown-none-elf`
- AVR: `avr-unknown-gnu-atmega328`

## WebAssembly

```rust
#![no_std]
extern crate alloc;

use synta::{Encoder, Encoding};
use synta::types::primitive::Integer;

#[no_mangle]
pub extern "C" fn encode_number(value: i64) -> *mut u8 {
    let int = Integer::from(value);
    let mut encoder = Encoder::new(Encoding::Der);
    encoder.encode(&int).unwrap();
    let bytes = encoder.finish().unwrap();
    bytes.as_ptr() as *mut u8
}
```

## Memory usage notes

### Stack usage (SmallVec optimization)

- Integer: stack-allocated for values up to 16 bytes
- OID: stack-allocated for paths up to 8 components

### Heap usage (when alloc is enabled)

- SEQUENCE/SET: allocate for element storage
- Strings: allocate for content
- Large integers/OIDs: spill to heap when exceeding SmallVec capacity