Skip to main content

macroonz_compiler/codec/
render.rs

1//! The token orchestrator for one codec surface.
2//!
3//! Refusal declaration, writing, reading, placement, and Rust-token spelling are separate operations beside this one, all under the codec home's one semantic owner.
4
5use super::declare::{refusal_conversion, refusal_declaration};
6use super::place::published_module;
7use super::read::decode_road;
8use super::spell::type_path;
9use super::write::encode_road;
10use super::{CodecContent, CodecPlacement, CodecProjection};
11use crate::bounded::Overflow;
12use crate::kind::SoleRole;
13use crate::plan::Plan;
14use crate::render::{Output, RenderError};
15use crate::token::{GeneratedToken, GeneratedTree, implementation};
16
17/// Render the one unit a codec request produces.
18///
19/// Naming the seat is the whole call: everything else the unit answers to is that seat's planned member, read by the sink.
20///
21/// # Errors
22///
23/// Returns [`RenderError::SeatUnplanned`] where the plan declares no member under the kind's one seat, [`RenderError::BytesUnbounded`] where the surface passes the rendered-byte magnitude, and [`RenderError::TokensUnbounded`] where a level of it passes the per-level one.
24pub fn render_codec(
25    plan: &Plan<CodecProjection>,
26    out: &mut Output<'_, CodecProjection>,
27) -> Result<(), RenderError> {
28    let tree = codec_surface(plan.content())?;
29    out.unit(SoleRole::Sole, tree)
30}
31
32/// The whole surface: the refusal the decode road answers with, the conversion a checked assembly earns, the roads the direction covers, and the placement carrying them.
33///
34/// The refusal and the conversion are rendered only where the direction covers the decode road, so an encode-only surface declares nothing that cannot happen — and carries no reader, which is what an encode-only direction means.
35///
36/// # Errors
37///
38/// Returns [`Overflow`] where a level of the surface passes the declared per-level token magnitude.
39pub fn codec_surface(content: &CodecContent) -> Result<GeneratedTree, Overflow> {
40    let shape = &content.shape;
41    let reads = content.direction.reads();
42    let mut tokens: Vec<GeneratedToken> = Vec::new();
43    if reads {
44        tokens.extend(refusal_declaration(shape)?);
45        tokens.extend(refusal_conversion(shape)?);
46    }
47    let mut inherent: Vec<GeneratedToken> = Vec::new();
48    if content.direction.writes() {
49        inherent.extend(encode_road(shape)?);
50    }
51    if reads {
52        inherent.extend(decode_road(shape)?);
53    }
54    tokens.extend(implementation(
55        Vec::new(),
56        Vec::new(),
57        None,
58        type_path(shape.owner()),
59        Vec::new(),
60        inherent,
61    )?);
62    let placed = match &content.placement {
63        CodecPlacement::AtDeclarationSite => tokens,
64        CodecPlacement::PublishedModule { spelling } => {
65            published_module(spelling.spelling(), tokens)?
66        }
67    };
68    GeneratedTree::assembled(placed)
69}