# Constructed Types
## SEQUENCE
A SEQUENCE is an ordered collection of elements of potentially different types.
Its DER tag is `0x30`.
```rust
use synta::types::constructed::{Element, Sequence};
use synta::types::primitive::{Boolean, Integer};
// Build
let mut seq = Sequence::new();
seq.push(Element::Integer(Integer::from(1)));
seq.push(Element::Boolean(Boolean::new(true)));
// Decode
let mut decoder = Decoder::new(&data, Encoding::Der);
let seq: Sequence = decoder.decode()?;
// Consuming iteration (lazy decode)
for element in seq {
match element? {
Element::Integer(i) => println!("Integer: {}", i.as_i64()?),
Element::Boolean(b) => println!("Boolean: {}", b.value()),
Element::OctetString(o) => println!("OctetString: {} bytes", o.as_bytes().len()),
_ => {}
}
}
```
## SET
A SET is similar to SEQUENCE but elements are unordered on the wire. In DER,
SET elements are encoded in sorted order (by DER encoding of each element).
Its tag is `0x31`.
```rust
use synta::types::constructed::{Element, Set};
let mut set = Set::new();
set.push(Element::Integer(Integer::from(10)));
set.push(Element::Integer(Integer::from(5)));
// DER encoder sorts elements lexicographically
```
## SEQUENCE OF
A `SEQUENCE OF T` is a homogeneous ordered collection of elements of type `T`.
Generated as `Vec<T>` — encodes with tag `0x30`.
```rust
use synta::types::constructed::SequenceOf;
use synta::types::primitive::Integer;
let mut seq_of = SequenceOf::<Integer>::new();
seq_of.push(Integer::from(1));
seq_of.push(Integer::from(2));
seq_of.push(Integer::from(3));
for int in seq_of.elements() {
println!("{}", int.as_i64()?);
}
```
## SET OF
A `SET OF T` is a homogeneous unordered collection. Generated as `SetOf<T>` —
encodes with tag `0x31`.
```rust
use synta::SetOf;
use synta::types::primitive::Integer;
let mut set_of = SetOf::<Integer>::new();
set_of.push(Integer::from(3));
set_of.push(Integer::from(1));
// DER encoder sorts elements by their encoded form
```
## CHOICE
CHOICE is an enumeration of alternative types; exactly one alternative is
present on the wire. Generated types use a Rust `enum`:
```asn1
Value ::= CHOICE {
integer INTEGER,
text UTF8String
}
```
Generated:
```rust
pub enum Value {
Integer(synta::Integer),
Text(synta::Utf8String),
}
```
Usage:
```rust
let value: Value = decoder.decode()?;
match value {
Value::Integer(i) => println!("integer: {}", i.as_i64()?),
Value::Text(s) => println!("text: {}", s.as_str()),
}
```
## Element — dynamic type dispatch
`Element` represents any ASN.1 value without a statically known type. Use it
when the type is only known at runtime or for schema-less parsing.
```rust
use synta::types::constructed::Element;
let element: Element = decoder.decode()?;
match element {
Element::Integer(i) => {},
Element::Boolean(b) => {},
Element::OctetString(o) => {},
Element::BitString(bs) => {},
Element::ObjectIdentifier(oid) => {},
Element::Null(n) => {},
Element::Utf8String(s) => {},
Element::Sequence(seq) => {
let elems = seq.into_elements()?;
// recursively process
}
Element::Set(set) => {},
Element::Tagged(tag, inner) => {},
_ => {},
}
```
## SeqRepr and lazy element parsing
`Sequence` and `Set` use a lazy internal representation. A freshly decoded
`Sequence` stores the raw DER span (`SeqRepr::Borrowed`); elements are only
parsed when iteration begins. This means decoding a large SEQUENCE is O(1) —
the full content is not parsed until you iterate.
```rust
// O(1) — only reads the SEQUENCE tag and length
let seq: Sequence = decoder.decode()?;
// Parsing happens here, on first iteration
for element in seq {
let elem = element?;
// ...
}
```
## Nested sequence pattern
```rust
use synta::types::constructed::Element;
fn parse_unknown(data: &[u8]) -> synta::Result<()> {
let mut decoder = Decoder::new(data, Encoding::Der);
let element: Element = decoder.decode()?;
match element {
Element::Sequence(s) => {
let elements = s.into_elements()?;
println!("Sequence with {} elements", elements.len());
for elem in &elements {
// process each element
}
}
_ => {}
}
Ok(())
}
```
## Roundtrip: encode then decode
```rust
use synta::types::constructed::{Element, Sequence};
use synta::types::primitive::Integer;
use synta::{Encoder, Decoder, Encoding};
// Build and encode
let mut seq = Sequence::new();
seq.push(Element::Integer(Integer::from(42)));
let mut encoder = Encoder::new(Encoding::Der);
encoder.encode(&seq)?;
let encoded = encoder.finish()?;
// Decode
let mut decoder = Decoder::new(&encoded, Encoding::Der);
let decoded: Sequence = decoder.decode()?;
```