otter/codec/bool.rs
1//! `Encoder`/`Decoder` for `bool` <-> the atoms `true`/`false`.
2//!
3//! Erlang has no boolean type; `true` and `false` are ordinary atoms, always
4//! present in the global atom table. Encoding yields the matching atom; decoding
5//! accepts exactly those two atoms and rejects every other term (including other
6//! atoms) as [`CodecError::WrongType`].
7
8use crate::codec::{CodecError, Decoder, Encoder};
9use crate::types::{AnyTerm, Atom, Env};
10
11/// Yields the atom `true` or `false`. Infallible — both are always interned.
12impl<'id> Encoder<'id> for bool {
13 fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
14 let name = if *self { "true" } else { "false" };
15 // `true`/`false` are reserved atoms, always interned, so the lookup
16 // never fails.
17 Atom::try_existing(env, name).expect("true/false atoms are always present").encode(env)
18 }
19}
20
21/// Accepts exactly the atoms `true`/`false`; every other term — including any
22/// other atom — is [`WrongType`](CodecError::WrongType).
23impl<'id> Decoder<'id> for bool {
24 fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
25 let atom = Atom::decode(term, env)?;
26 if atom == Atom::try_existing(env, "true").expect("true atom is always present") {
27 Ok(true)
28 } else if atom == Atom::try_existing(env, "false").expect("false atom is always present") {
29 Ok(false)
30 } else {
31 Err(CodecError::WrongType)
32 }
33 }
34}