Skip to main content

macroonz_compiler/descriptor/mutation/
render.rs

1//! The token half of the mutation road: the module a mutation harness lowers and invokes.
2//!
3//! # What is rendered, and what is only carried
4//!
5//! The discovery, the policy, and the dispatch are rendered from the declaration.
6//! The production expression and every alternative's meaning are carried through unread: they are token material the door computed from the declaration it captured, and a renderer that interpreted them would be deciding what the consumer's declaration means.
7//!
8//! # Nothing spells a crate
9//!
10//! Every path begins with the harness binding's own metavariable, so a consumer that renamed the dependency gets its own name back.
11
12use super::{Alternative, Permission, Policy, Site, Surface};
13use crate::bounded::Overflow;
14use crate::descriptor::vocabulary::{self, HarnessName};
15use crate::descriptor::{Name, TypeName};
16use crate::stamp::{Visibility, declared_reach_tokens};
17use crate::token::{
18    GeneratedDelimiter, GeneratedToken, and_all, bound_local, call, comma_many, constant, equality,
19    function, group, method_call, method_chain, result_type, roster, text_pair,
20};
21
22/// The refusal arm a refused namespaced reference reaches.
23const NAME_ARM: &str = "Name";
24
25/// The refusal arm a refused permission reaches.
26const PERMISSION_ARM: &str = "Permission";
27
28/// The refusal arm a refused policy reaches.
29const POLICY_ARM: &str = "Policy";
30
31/// The refusal arm a refused discovery reaches.
32const DISCOVERY_ARM: &str = "Discovery";
33
34/// The refusal arm a refused lowering reaches.
35const LOWERING_ARM: &str = "Lowering";
36
37/// The refusal arm a slug the address does not resolve reaches.
38const UNRESOLVED_ARM: &str = "OperatorFamilyNotFound";
39
40/// The road a bench target invokes to lower the rendered surface.
41const LOWERING: &str = "lowering";
42
43/// The road the unchanged declaration answers through.
44const PRODUCTION: &str = "production";
45
46/// The road an evaluation is called through.
47const EVALUATION: &str = "evaluation";
48
49/// The road the rendered alternatives are read back through.
50const CANDIDATES: &str = "candidate_orders";
51
52/// The local the lowering binds its evaluation family to.
53const FAMILY_LOCAL: &str = "family";
54
55/// The local the lowering binds its complete policy to.
56const POLICY_LOCAL: &str = "policy";
57
58/// The local the site binds its point to.
59const POINT_LOCAL: &str = "point";
60
61/// The local the site binds its activation to.
62const ACTIVATION_LOCAL: &str = "activation";
63
64/// The local the site binds its owner claim to.
65const OWNER_CLAIM_LOCAL: &str = "owner_claim";
66
67/// The local the lowering binds its one discovered site to.
68const SITE_LOCAL: &str = "site";
69
70/// The local an evaluation binds its resolved selection to.
71const RESOLVED_LOCAL: &str = "resolved";
72
73/// The parameter every rendered road takes and none of them reads.
74const INPUT_PARAMETER: &str = "_input";
75
76/// The lifetime an evaluation directive is borrowed for.
77const SURFACE_LIFETIME: &str = "surface";
78
79/// The stem every rendered alternative constant is named from.
80const ALTERNATIVE_STEM: &str = "ALTERNATIVE";
81
82/// Render the module a mutation harness lowers and invokes.
83///
84/// # Errors
85///
86/// Returns [`Overflow`] where the module outgrows the declared magnitude.
87pub fn generated_module(surface: &Surface) -> Result<Vec<GeneratedToken>, Overflow> {
88    let refusal = &surface.address().refusal;
89    let site = surface.site();
90    let mut body = refusal_type(refusal)?;
91    body.extend(alternative_constants(site));
92    body.extend(candidate_orders(site)?);
93    body.extend(lowering(surface)?);
94    body.extend(production(site)?);
95    body.extend(evaluation(site)?);
96    let mut tokens = declared_reach_tokens(Visibility::Crate)?;
97    tokens.push(GeneratedToken::word("mod"));
98    tokens.push(GeneratedToken::word(surface.address().module.spelling()));
99    tokens.push(group(GeneratedDelimiter::Brace, body)?);
100    Ok(tokens)
101}
102
103/// The refusal type the module declares and every lowering road answers in.
104fn refusal_type(refusal: &TypeName) -> Result<Vec<GeneratedToken>, Overflow> {
105    let carried = [
106        (NAME_ARM, HarnessName::Descriptor, HarnessName::NameRefusal),
107        (
108            PERMISSION_ARM,
109            HarnessName::Muterprater,
110            HarnessName::PermissionRefusal,
111        ),
112        (
113            POLICY_ARM,
114            HarnessName::Muterprater,
115            HarnessName::PolicyRefusal,
116        ),
117        (
118            DISCOVERY_ARM,
119            HarnessName::Muterprater,
120            HarnessName::DiscoveryRefusal,
121        ),
122        (
123            LOWERING_ARM,
124            HarnessName::Muterprater,
125            HarnessName::DiscoveryLoweringRefusal,
126        ),
127    ];
128    let mut arms: Vec<GeneratedToken> = Vec::new();
129    for (arm, module, kind) in carried {
130        arms.push(GeneratedToken::word(arm));
131        arms.push(group(
132            GeneratedDelimiter::Parenthesis,
133            vocabulary::path(&[module, kind]),
134        )?);
135        arms.push(GeneratedToken::alone(','));
136    }
137    arms.push(GeneratedToken::word(UNRESOLVED_ARM));
138    arms.push(GeneratedToken::alone(','));
139
140    let mut tokens = vec![
141        GeneratedToken::alone('#'),
142        group(
143            GeneratedDelimiter::Bracket,
144            vec![
145                GeneratedToken::word("derive"),
146                group(
147                    GeneratedDelimiter::Parenthesis,
148                    vec![GeneratedToken::word("Debug")],
149                )?,
150            ],
151        )?,
152    ];
153    tokens.extend(declared_reach_tokens(Visibility::Crate)?);
154    tokens.push(GeneratedToken::word("enum"));
155    tokens.push(GeneratedToken::word(refusal.spelling()));
156    tokens.push(group(GeneratedDelimiter::Brace, arms)?);
157    Ok(tokens)
158}
159
160/// The name one alternative's rendered constant carries.
161fn alternative_name(position: usize) -> String {
162    format!("{ALTERNATIVE_STEM}_{position}")
163}
164
165/// One constant per declared alternative, each holding the value that alternative means.
166fn alternative_constants(site: &Site) -> Vec<GeneratedToken> {
167    let mut tokens: Vec<GeneratedToken> = Vec::new();
168    for (position, alternative) in site.alternatives().iter().enumerate() {
169        tokens.extend(constant(
170            &alternative_name(position),
171            site.order().to_vec(),
172            alternative.meaning().to_vec(),
173        ));
174    }
175    tokens
176}
177
178/// The road the rendered alternatives are read back through, as one array of the declared width.
179fn candidate_orders(site: &Site) -> Result<Vec<GeneratedToken>, Overflow> {
180    let mut values: Vec<GeneratedToken> = Vec::new();
181    for position in 0..site.alternatives().len() {
182        values.push(GeneratedToken::word(&alternative_name(position)));
183        values.push(GeneratedToken::alone(','));
184    }
185    let mut result = site.order().to_vec();
186    result.push(GeneratedToken::alone(';'));
187    result.push(GeneratedToken::number(
188        u64::try_from(site.alternatives().len()).unwrap_or(u64::MAX),
189    ));
190    let mut tokens = declared_reach_tokens(Visibility::Crate)?;
191    tokens.extend(function(
192        CANDIDATES,
193        Vec::new(),
194        vec![group(GeneratedDelimiter::Bracket, result)?],
195        vec![group(GeneratedDelimiter::Bracket, values)?],
196    )?);
197    Ok(tokens)
198}
199
200/// One expression with `.map_err(<Refusal>::<arm>)?` on it.
201fn mapped(
202    expression: Vec<GeneratedToken>,
203    refusal: &TypeName,
204    arm: &str,
205) -> Result<Vec<GeneratedToken>, Overflow> {
206    let mut tokens = method_call(expression, "map_err", arm_path(refusal, arm))?;
207    tokens.push(GeneratedToken::alone('?'));
208    Ok(tokens)
209}
210
211/// One expression with `.ok_or(<Refusal>::<arm>)?` on it.
212fn or_refused(
213    expression: Vec<GeneratedToken>,
214    refusal: &TypeName,
215    arm: &str,
216) -> Result<Vec<GeneratedToken>, Overflow> {
217    let mut tokens = method_call(expression, "ok_or", arm_path(refusal, arm))?;
218    tokens.push(GeneratedToken::alone('?'));
219    Ok(tokens)
220}
221
222/// One arm of the rendered refusal type, as a path.
223fn arm_path(refusal: &TypeName, arm: &str) -> Vec<GeneratedToken> {
224    vec![
225        GeneratedToken::word(refusal.spelling()),
226        GeneratedToken::joint(':'),
227        GeneratedToken::alone(':'),
228        GeneratedToken::word(arm),
229    ]
230}
231
232/// One namespaced name as the two text literals its parser takes.
233fn name_arguments(name: &Name) -> Vec<GeneratedToken> {
234    text_pair(name.namespace(), name.stem())
235}
236
237/// One byte string as the owned vector the address's constructors take.
238fn owned_bytes(material: &[u8]) -> Result<Vec<GeneratedToken>, Overflow> {
239    method_chain(vec![GeneratedToken::byte_text(material)], &["to_vec"])
240}
241
242/// The locals the policy is built from: the evaluation family, then one claim, its families, and its permission per declared row.
243fn policy_locals(policy: &Policy, refusal: &TypeName) -> Result<Vec<GeneratedToken>, Overflow> {
244    let mut body = bound_local(
245        FAMILY_LOCAL,
246        mapped(
247            vocabulary::road(
248                &[
249                    HarnessName::Muterprater,
250                    HarnessName::EvaluationFamilyRef,
251                    HarnessName::Named,
252                ],
253                name_arguments(policy.family()),
254            )?,
255            refusal,
256            NAME_ARM,
257        )?,
258    );
259    for (position, permission) in policy.permissions().iter().enumerate() {
260        body.extend(permission_locals(permission, position, refusal)?);
261    }
262    let mut named: Vec<GeneratedToken> = Vec::new();
263    for position in 0..policy.permissions().len() {
264        named.push(GeneratedToken::word(&format!("permission_{position}")));
265        named.push(GeneratedToken::alone(','));
266    }
267    body.extend(bound_local(
268        POLICY_LOCAL,
269        mapped(
270            vocabulary::road(
271                &[
272                    HarnessName::Muterprater,
273                    HarnessName::MutationPolicy,
274                    HarnessName::Declared,
275                ],
276                comma_many(vec![
277                    vec![GeneratedToken::word(FAMILY_LOCAL)],
278                    roster(named)?,
279                ]),
280            )?,
281            refusal,
282            POLICY_ARM,
283        )?,
284    ));
285    Ok(body)
286}
287
288/// One permission's own locals: its claim, one local per operator family it names, and the permission itself.
289fn permission_locals(
290    permission: &Permission,
291    position: usize,
292    refusal: &TypeName,
293) -> Result<Vec<GeneratedToken>, Overflow> {
294    let claim = format!("permission_claim_{position}");
295    let mut body = bound_local(
296        &claim,
297        mapped(
298            vocabulary::road(
299                &[
300                    HarnessName::Descriptor,
301                    HarnessName::ClaimRef,
302                    HarnessName::Named,
303                ],
304                name_arguments(permission.claim()),
305            )?,
306            refusal,
307            NAME_ARM,
308        )?,
309    );
310    let mut named: Vec<GeneratedToken> = Vec::new();
311    for (seat, family) in permission.families().iter().enumerate() {
312        let local = format!("permission_family_{position}_{seat}");
313        body.extend(bound_local(
314            &local,
315            or_refused(family_reference(family.slug())?, refusal, UNRESOLVED_ARM)?,
316        ));
317        named.push(GeneratedToken::word(&local));
318        named.push(GeneratedToken::alone(','));
319    }
320    body.extend(bound_local(
321        &format!("permission_{position}"),
322        mapped(
323            vocabulary::road(
324                &[
325                    HarnessName::Muterprater,
326                    HarnessName::MutationPermission,
327                    HarnessName::Declared,
328                ],
329                comma_many(vec![vec![GeneratedToken::word(&claim)], roster(named)?]),
330            )?,
331            refusal,
332            PERMISSION_ARM,
333        )?,
334    ));
335    Ok(body)
336}
337
338/// One operator family, resolved from the slug the declaration named it by.
339fn family_reference(slug: &str) -> Result<Vec<GeneratedToken>, Overflow> {
340    vocabulary::road(
341        &[
342            HarnessName::Muterprater,
343            HarnessName::OperatorFamilyRef,
344            HarnessName::OfSlug,
345        ],
346        vec![GeneratedToken::text(slug)],
347    )
348}
349
350/// The locals the one discovered site is built from.
351fn site_locals(
352    site: &Site,
353    policy: &Policy,
354    refusal: &TypeName,
355) -> Result<Vec<GeneratedToken>, Overflow> {
356    let mut body = bound_local(
357        POINT_LOCAL,
358        mapped(
359            vocabulary::road(
360                &[
361                    HarnessName::Descriptor,
362                    HarnessName::MutationPointRef,
363                    HarnessName::Named,
364                ],
365                name_arguments(site.point()),
366            )?,
367            refusal,
368            NAME_ARM,
369        )?,
370    );
371    body.extend(bound_local(
372        ACTIVATION_LOCAL,
373        mapped(
374            vocabulary::road(
375                &[
376                    HarnessName::Muterprater,
377                    HarnessName::ActivationSite,
378                    HarnessName::Named,
379                ],
380                name_arguments(site.point()),
381            )?,
382            refusal,
383            NAME_ARM,
384        )?,
385    ));
386    let mapping = match policy.claim_for(site.fact()) {
387        Some(claim) => {
388            body.extend(bound_local(
389                OWNER_CLAIM_LOCAL,
390                mapped(
391                    vocabulary::road(
392                        &[
393                            HarnessName::Descriptor,
394                            HarnessName::ClaimRef,
395                            HarnessName::Named,
396                        ],
397                        name_arguments(claim),
398                    )?,
399                    refusal,
400                    NAME_ARM,
401                )?,
402            ));
403            call(
404                vocabulary::path(&[
405                    HarnessName::Muterprater,
406                    HarnessName::OwnerClaimMapping,
407                    HarnessName::Mapped,
408                ]),
409                vec![GeneratedToken::word(OWNER_CLAIM_LOCAL)],
410            )?
411        }
412        None => vocabulary::path(&[
413            HarnessName::Muterprater,
414            HarnessName::OwnerClaimMapping,
415            HarnessName::OwnerUnmapped,
416        ]),
417    };
418    body.extend(bound_local(
419        SITE_LOCAL,
420        mapped(discovered(site, mapping, refusal)?, refusal, DISCOVERY_ARM)?,
421    ));
422    Ok(body)
423}
424
425/// The one discovered site, over the point, the owner-claim mapping, the unchanged operation, and every declared alternative.
426fn discovered(
427    site: &Site,
428    mapping: Vec<GeneratedToken>,
429    refusal: &TypeName,
430) -> Result<Vec<GeneratedToken>, Overflow> {
431    let mut candidates: Vec<GeneratedToken> = Vec::new();
432    for alternative in site.alternatives() {
433        candidates.extend(stated(alternative, refusal)?);
434        candidates.push(GeneratedToken::alone(','));
435    }
436    vocabulary::road(
437        &[
438            HarnessName::Muterprater,
439            HarnessName::DiscoveredMutationSite,
440            HarnessName::Discovered,
441        ],
442        comma_many(vec![
443            vec![GeneratedToken::word(POINT_LOCAL)],
444            mapping,
445            owned_bytes(site.unchanged())?,
446            roster(candidates)?,
447            vec![GeneratedToken::word(ACTIVATION_LOCAL)],
448        ]),
449    )
450}
451
452/// One declared alternative, as the address's own declaration of it.
453fn stated(alternative: &Alternative, refusal: &TypeName) -> Result<Vec<GeneratedToken>, Overflow> {
454    let family = or_refused(
455        family_reference(alternative.family().slug())?,
456        refusal,
457        UNRESOLVED_ARM,
458    )?;
459    vocabulary::road(
460        &[
461            HarnessName::Muterprater,
462            HarnessName::AlternativeDeclaration,
463            HarnessName::Stated,
464        ],
465        comma_many(vec![family, owned_bytes(alternative.operation())?]),
466    )
467}
468
469/// The road a harness invokes to lower this surface's one discovered site under its policy.
470fn lowering(surface: &Surface) -> Result<Vec<GeneratedToken>, Overflow> {
471    let refusal = &surface.address().refusal;
472    let policy = surface.policy();
473    let mut body = policy_locals(policy, refusal)?;
474    body.extend(site_locals(surface.site(), policy, refusal)?);
475    let lowered = vocabulary::road(
476        &[
477            HarnessName::Muterprater,
478            HarnessName::Discover,
479            HarnessName::LowerDiscoveries,
480        ],
481        comma_many(vec![
482            vec![
483                GeneratedToken::alone('&'),
484                GeneratedToken::word(POLICY_LOCAL),
485            ],
486            roster(vec![
487                GeneratedToken::word(SITE_LOCAL),
488                GeneratedToken::alone(','),
489            ])?,
490        ]),
491    )?;
492    body.extend(method_call(
493        lowered,
494        "map_err",
495        arm_path(refusal, LOWERING_ARM),
496    )?);
497    let mut tokens = declared_reach_tokens(Visibility::Crate)?;
498    tokens.extend(function(
499        LOWERING,
500        Vec::new(),
501        result_type(
502            vocabulary::path(&[
503                HarnessName::Muterprater,
504                HarnessName::MutationSurfaceLowering,
505            ]),
506            vec![GeneratedToken::word(refusal.spelling())],
507        ),
508        body,
509    )?);
510    Ok(tokens)
511}
512
513/// The road the unchanged declaration answers through.
514fn production(site: &Site) -> Result<Vec<GeneratedToken>, Overflow> {
515    let mut tokens = declared_reach_tokens(Visibility::Crate)?;
516    tokens.extend(function(
517        PRODUCTION,
518        input_parameter()?,
519        site.order().to_vec(),
520        site.production().to_vec(),
521    )?);
522    Ok(tokens)
523}
524
525/// The one parameter every rendered road takes and none of them reads.
526fn input_parameter() -> Result<Vec<GeneratedToken>, Overflow> {
527    Ok(vec![
528        GeneratedToken::word(INPUT_PARAMETER),
529        GeneratedToken::alone(':'),
530        GeneratedToken::alone('&'),
531        group(GeneratedDelimiter::Parenthesis, Vec::new())?,
532    ])
533}
534
535/// The road an evaluation is called through: the production where nothing was selected, the selected alternative where one was, and a refusal where the selection names something this rendering does not carry.
536fn evaluation(site: &Site) -> Result<Vec<GeneratedToken>, Overflow> {
537    let observation = observation_type(site);
538    let mut body = unselected()?;
539    for (position, alternative) in site.alternatives().iter().enumerate() {
540        body.push(GeneratedToken::word("if"));
541        body.extend(active_condition(site, alternative)?);
542        body.push(group(
543            GeneratedDelimiter::Brace,
544            observed(vec![GeneratedToken::word(&alternative_name(position))], 1)?,
545        )?);
546    }
547    body.extend(call(
548        vec![GeneratedToken::word("Err")],
549        call(
550            vocabulary::path(&[
551                HarnessName::Muterprater,
552                HarnessName::EvaluationCallRefusal,
553                HarnessName::ActiveSelectionNotImplemented,
554            ]),
555            method_chain(
556                vec![GeneratedToken::word(RESOLVED_LOCAL)],
557                &[HarnessName::Selection.spelling()],
558            )?,
559        )?,
560    )?);
561
562    let mut tokens = declared_reach_tokens(Visibility::Crate)?;
563    tokens.push(GeneratedToken::word("fn"));
564    tokens.push(GeneratedToken::word(EVALUATION));
565    tokens.extend(surface_lifetime());
566    tokens.push(group(
567        GeneratedDelimiter::Parenthesis,
568        directive_parameters()?,
569    )?);
570    tokens.push(GeneratedToken::joint('-'));
571    tokens.push(GeneratedToken::alone('>'));
572    tokens.extend(result_type(
573        observation,
574        vocabulary::path(&[HarnessName::Muterprater, HarnessName::EvaluationCallRefusal]),
575    ));
576    tokens.push(group(GeneratedDelimiter::Brace, body)?);
577    Ok(tokens)
578}
579
580/// The lifetime an evaluation directive is borrowed for, as the tokens that spell it.
581fn surface_lifetime() -> Vec<GeneratedToken> {
582    vec![
583        GeneratedToken::alone('<'),
584        GeneratedToken::joint('\''),
585        GeneratedToken::word(SURFACE_LIFETIME),
586        GeneratedToken::alone('>'),
587    ]
588}
589
590/// The parameters an evaluation takes: the input nothing reads, and the directive it answers under.
591fn directive_parameters() -> Result<Vec<GeneratedToken>, Overflow> {
592    let mut tokens = input_parameter()?;
593    tokens.push(GeneratedToken::alone(','));
594    tokens.push(GeneratedToken::word("directive"));
595    tokens.push(GeneratedToken::alone(':'));
596    tokens.extend(vocabulary::path(&[
597        HarnessName::Muterprater,
598        HarnessName::EvaluationDirective,
599    ]));
600    tokens.extend(surface_lifetime());
601    Ok(tokens)
602}
603
604/// The observation an evaluation answers with, over the type the alternatives are values of.
605fn observation_type(site: &Site) -> Vec<GeneratedToken> {
606    let mut tokens =
607        vocabulary::path(&[HarnessName::Muterprater, HarnessName::EvaluationObservation]);
608    tokens.push(GeneratedToken::alone('<'));
609    tokens.extend(site.order().to_vec());
610    tokens.push(GeneratedToken::alone('>'));
611    tokens
612}
613
614/// The `let … else` that answers with the production where the directive resolved no selection.
615fn unselected() -> Result<Vec<GeneratedToken>, Overflow> {
616    let resolved = method_chain(
617        vec![GeneratedToken::word("directive")],
618        &[HarnessName::Resolved.spelling()],
619    )?;
620    let mut tokens = vec![
621        GeneratedToken::word("let"),
622        GeneratedToken::word("Some"),
623        group(
624            GeneratedDelimiter::Parenthesis,
625            vec![GeneratedToken::word(RESOLVED_LOCAL)],
626        )?,
627        GeneratedToken::alone('='),
628    ];
629    tokens.extend(resolved);
630    tokens.push(GeneratedToken::word("else"));
631    tokens.push(group(
632        GeneratedDelimiter::Brace,
633        observed(
634            call(
635                vec![GeneratedToken::word(PRODUCTION)],
636                vec![GeneratedToken::word(INPUT_PARAMETER)],
637            )?,
638            0,
639        )?,
640    )?);
641    tokens.push(GeneratedToken::alone(';'));
642    Ok(tokens)
643}
644
645/// One `return Ok(<observation>);` over the meaning an evaluation answers with and how many times it fired.
646fn observed(meaning: Vec<GeneratedToken>, firings: u64) -> Result<Vec<GeneratedToken>, Overflow> {
647    let taken = vocabulary::road(
648        &[
649            HarnessName::Muterprater,
650            HarnessName::EvaluationObservation,
651            HarnessName::Observed,
652        ],
653        comma_many(vec![meaning, vec![GeneratedToken::number(firings)]]),
654    )?;
655    let mut tokens = vec![GeneratedToken::word("return")];
656    tokens.extend(call(vec![GeneratedToken::word("Ok")], taken)?);
657    tokens.push(GeneratedToken::alone(';'));
658    Ok(tokens)
659}
660
661/// The condition one alternative's arm fires under: the point, the operator family, and the operation, all compared against what the resolved selection carries.
662fn active_condition(
663    site: &Site,
664    alternative: &Alternative,
665) -> Result<Vec<GeneratedToken>, Overflow> {
666    let point = site.point();
667    let comparisons = vec![
668        equality(
669            selected_point(&[HarnessName::NamespaceRoad, HarnessName::Written])?,
670            vec![GeneratedToken::text(point.namespace())],
671        ),
672        equality(
673            selected_point(&[HarnessName::StemRoad, HarnessName::Written])?,
674            vec![GeneratedToken::text(point.stem())],
675        ),
676        equality(
677            method_chain(
678                vec![GeneratedToken::word(RESOLVED_LOCAL)],
679                &[
680                    HarnessName::Alternative.spelling(),
681                    HarnessName::Family.spelling(),
682                    HarnessName::Slug.spelling(),
683                ],
684            )?,
685            vec![GeneratedToken::text(alternative.family().slug())],
686        ),
687        equality(
688            method_chain(
689                vec![GeneratedToken::word(RESOLVED_LOCAL)],
690                &[
691                    HarnessName::Alternative.spelling(),
692                    HarnessName::Operation.spelling(),
693                ],
694            )?,
695            vec![GeneratedToken::byte_text(alternative.operation())],
696        ),
697    ];
698    Ok(and_all(comparisons))
699}
700
701/// One reading of the resolved selection's own point name.
702fn selected_point(part: &[HarnessName]) -> Result<Vec<GeneratedToken>, Overflow> {
703    let mut roads = vec![
704        HarnessName::Point.spelling(),
705        HarnessName::Identity.spelling(),
706        HarnessName::NameRoad.spelling(),
707    ];
708    roads.extend(part.iter().map(|road| road.spelling()));
709    method_chain(vec![GeneratedToken::word(RESOLVED_LOCAL)], &roads)
710}