otter/codec/bigint.rs
1//! `Encoder`/`Decoder` for [`num_bigint::BigInt`] — arbitrary-precision Erlang
2//! integers, including bignums beyond `i64`/`u64`. Gated behind the `bigint`
3//! feature.
4//!
5//! Both directions go through [`Integer::from_bigint`]/[`Integer::to_bigint`],
6//! which use the external term format for the >64-bit cases (the NIF API has no
7//! bignum accessor). A non-integer term decodes as [`CodecError::WrongType`];
8//! encoding never fails.
9
10use num_bigint::BigInt;
11
12use crate::codec::{CodecError, Decoder, Encoder};
13use crate::types::{AnyTerm, Env, Integer};
14
15/// Encodes any magnitude via [`Integer::from_bigint`] (an `i64`/`u64` fast path,
16/// else ETF). Infallible.
17impl<'id> Encoder<'id> for BigInt {
18 fn encode(&self, env: impl Env<'id>) -> Result<AnyTerm<'id>, CodecError> {
19 Integer::from_bigint(env, self).encode(env)
20 }
21}
22
23/// Reads any integer term, however wide, via [`Integer::to_bigint`]. A
24/// non-integer term is [`WrongType`](CodecError::WrongType).
25impl<'id> Decoder<'id> for BigInt {
26 fn decode(term: AnyTerm<'id>, env: impl Env<'id>) -> Result<Self, CodecError> {
27 Ok(Integer::decode(term, env)?.to_bigint(env))
28 }
29}