synta 0.2.5

ASN.1 parser, decoder, and encoder library with DER/BER support and C FFI
Documentation
# Optional and Default Fields

## OPTIONAL fields

Fields marked `OPTIONAL` in ASN.1 are generated as `Option<T>` in the Rust
struct.  Field order matches the ASN.1 definition order.

ASN.1:

```asn1
TBSCertificate ::= SEQUENCE {
    version         [0] EXPLICIT INTEGER DEFAULT 0,
    serialNumber    INTEGER,
    issuerUniqueID  [1] IMPLICIT BIT STRING OPTIONAL
}
```

Generated Rust:

```rust
#[derive(Debug, Clone, PartialEq)]
pub struct Tbscertificate {
    pub version: Option<synta::Integer>,
    pub serial_number: synta::Integer,
    pub issuer_unique_id: Option<synta::BitString>,
}
```

## DEFAULT values

`#[derive(Default)]` is generated when **every** field is `OPTIONAL` and carries
no explicit `DEFAULT` value — in that case every field maps to `None`, which is
always the correct default.  When some fields are mandatory or carry explicit
DEFAULT values, no `Default` impl is generated.

Example — struct with only optional fields (gets `#[derive(Default)]`):

```asn1
Metadata ::= SEQUENCE {
    displayName UTF8String OPTIONAL,
    verified    BOOLEAN OPTIONAL
}
```

Generated Rust:

```rust
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Metadata {
    pub display_name: Option<Utf8String>,
    pub verified: Option<Boolean>,
}
```

Example — struct with a mandatory field (no `Default` derived):

```asn1
Profile ::= SEQUENCE {
    username    IA5String,
    displayName UTF8String OPTIONAL
}
```

Generated Rust:

```rust
#[derive(Debug, Clone, PartialEq)]
pub struct Profile {
    pub username: IA5String,
    pub display_name: Option<Utf8String>,
}
```

## Constructing optional fields

```rust
let profile = Profile {
    username: IA5String::new("alice".to_string()).unwrap(),
    display_name: Some(Utf8String::from("Alice".to_string())),
};
```

## Working with optional fields at runtime

```rust
if let Some(name) = &profile.display_name {
    println!("Display name: {}", name.as_str());
}

// Or use map/unwrap_or
let name = profile.display_name
    .as_ref()
    .map(|s| s.as_str())
    .unwrap_or("<none>");
```

## Supported DEFAULT value forms

The following DEFAULT value forms are parsed by synta-codegen:

| Form | Example |
|------|---------|
| Integer literal | `DEFAULT 0` |
| Boolean literal | `DEFAULT TRUE`, `DEFAULT FALSE` |
| NULL | `DEFAULT NULL` |
| Named value reference | `DEFAULT someConstant` |
| Object identifier | `DEFAULT { 1 2 840 }` |
| Bit string literal | `DEFAULT '0000'B` |
| Hex string literal | `DEFAULT 'DEADBEEF'H` |