[−][src]Module bcder::guide::encode
Encoding data in BER.
Note: This guide is still work in progress and will be extended.
In many cases, BER requires that a value can state the length of its encoded content before actually starting to encode this content. Since this requires duplicate code in many cases, we have decided to use placeholder objects for encoding. These placeholders, called value encoders, are available for most built-in types as well as for various constructions such as tuples, a specific type can produce a value encoder by manufacturing it from these existing parts.
To return to the example from the decoding guide. It was using this ASN.1:
EncapsulatedContentInfo ::= SEQUENCE {
eContentType ContentType,
eContent [0] EXPLICIT OCTET STRING OPTIONAL
}
ContentType ::= OBJECT IDENTIFIER
The structure was represented by this Rust struct:
use bcder::{Oid, OctetString}; pub struct EncapsulatedContentInfo { content_type: Oid, content: Option<OctetString>, }
The value encoders all implement the trait encode::Values
which
represents a sequence of BER-encodable values. The implementation of
our struct could return such an encoder like this:
use bcder::Tag; use bcder::encode; impl EncapsulatedContentInfo { pub fn encode(self) -> impl encode::Values { self.encode_as(Tag::SEQUENCE) } pub fn encode_as(self, tag: Tag) -> impl encode::Values { encode::sequence_as(tag, ( self.content_type.encode(), self.content.map(|s| s.encode()) )) } }
The conventional name for the method produces a value encoder with the
natural tag is encode
. If necessary, encode_as
should be present to
allow getting a value encoder with a chosen tag for implicit tagging.
The signature of these methods will most likely require a lifetime bound for the return value as in the example above, if the returned value contains references to the value or its elements. This is completely fine, since typically the returned value will only be used to encode the value right away and then dropped.