Skip to main content

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}