sim_codec_bitwise_base64/lib.rs
1//! Base64 text framing over the SIM bitwise codec.
2//!
3//! This crate is a thin text wrapper around `sim-codec-bitwise`: it produces and
4//! consumes the same bit-packed `Expr` frames, but carries them as a
5//! base64-encoded ASCII string so the canonical minimal codec can be used on
6//! text-only transports. It is the exact analog of `sim-codec-binary-base64`
7//! over the bitwise frame, and it shares that crate's base64 implementation
8//! rather than forking it. Encoding delegates to the bitwise codec and
9//! base64-encodes the resulting frame; decoding base64-decodes the text and
10//! hands the bytes back to the bitwise reader.
11//!
12//! The public surface is the [`BitwiseBase64Codec`] runtime object, registered
13//! via [`BitwiseBase64CodecLib`].
14//!
15//! # Examples
16//!
17//! Register the codec and round-trip an [`Expr`] through base64 text: encoding
18//! produces an ASCII string, and decoding that string recovers the value.
19//!
20//! ```
21//! use std::sync::Arc;
22//! use sim_codec::{Input, decode_with_codec, encode_with_codec};
23//! use sim_codec_bitwise_base64::BitwiseBase64CodecLib;
24//! use sim_kernel::{Cx, DefaultFactory, EagerPolicy, Expr, ReadPolicy, Symbol};
25//!
26//! let mut cx = Cx::new(Arc::new(EagerPolicy), Arc::new(DefaultFactory));
27//! sim_test_support::register_core_classes(&mut cx);
28//!
29//! let lib = BitwiseBase64CodecLib::new(cx.registry_mut().fresh_codec_id());
30//! cx.load_lib(&lib)?;
31//! let codec = Symbol::qualified("codec", "bitwise-base64");
32//!
33//! let expr = Expr::List(vec![Expr::Nil, Expr::Bool(true)]);
34//! let text = encode_with_codec(&mut cx, &codec, &expr, Default::default())?
35//! .into_text()?;
36//! assert!(text.is_ascii());
37//!
38//! let back = decode_with_codec(&mut cx, &codec, Input::Text(text), ReadPolicy::default())?;
39//! assert!(back.canonical_eq(&expr));
40//! # Ok::<(), sim_kernel::Error>(())
41//! ```
42//!
43//! The wrapped text is untrusted: input that is not valid base64 fails closed
44//! rather than being interpreted.
45//!
46//! ```
47//! use std::sync::Arc;
48//! use sim_codec::{Input, decode_with_codec};
49//! use sim_codec_bitwise_base64::BitwiseBase64CodecLib;
50//! use sim_kernel::{Cx, DefaultFactory, EagerPolicy, ReadPolicy, Symbol};
51//!
52//! let mut cx = Cx::new(Arc::new(EagerPolicy), Arc::new(DefaultFactory));
53//! sim_test_support::register_core_classes(&mut cx);
54//! let lib = BitwiseBase64CodecLib::new(cx.registry_mut().fresh_codec_id());
55//! cx.load_lib(&lib)?;
56//! let codec = Symbol::qualified("codec", "bitwise-base64");
57//!
58//! let result = decode_with_codec(
59//! &mut cx,
60//! &codec,
61//! Input::Text("not base64!".to_owned()),
62//! ReadPolicy::default(),
63//! );
64//! assert!(result.is_err());
65//! # Ok::<(), sim_kernel::Error>(())
66//! ```
67//!
68//! [`Expr`]: sim_kernel::Expr
69
70#![forbid(unsafe_code)]
71#![deny(missing_docs)]
72
73mod codec;
74#[cfg(test)]
75mod tests;
76
77pub use codec::{BitwiseBase64Codec, BitwiseBase64CodecLib};