makepad/libs/relax/compiler/tests/ctor_projection_field.rs
Admin b22a714840 makepad run: the Rust JIT (libs/relax) and makepad-remote
The JIT that runs makepad apps from source: lexer, front end, type checker,
lazy borrow checker (Gandalf; `--check-first` opts in), codegen, session and
warm/cold caches keyed by compiler stamp, provided crates bound late,
startup images, live patching. User-facing name is `makepad run` (binary
`makepad`, MAKEPAD_RUN_* env, ~/.makepad-run); libs/relax stays the internal
library name. `makepad check` reports rustc-style diagnostics with rustc
error codes and checks a whole workspace (`--workspace`). Runs on macOS,
Linux, Windows and Android. makepad-remote: one tool schema for apps and the
WM (app/1): grabs, captures, traces, frame profiles and tweaks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

46 lines
2.1 KiB
Rust

// A tuple struct whose field is declared through an associated type, built with its constructor
// from an argument whose type is that projection (`W(p.into_searcher(h))` in a generic fn):
// the constructor's signature is instantiated AND normalized like any fn's, so the argument is
// passed as the concrete type (core::str::MatchIndices(P::Searcher) -- `s.replace(|c| .., "_")`
// read a garbage haystack and crashed under `makepad run`).
pub trait Pat<'a> { type S: Srch<'a>; fn into_s(self, h: &'a str) -> Self::S; }
pub trait Srch<'a> { fn hay(&self) -> &'a str; fn pos(&self) -> usize; }
pub struct PredS<'a, F> { f: F, h: &'a str, pos: usize }
impl<'a, F: FnMut(char) -> bool> Srch<'a> for PredS<'a, F> { fn hay(&self) -> &'a str { self.h } fn pos(&self) -> usize { self.pos } }
impl<'a, F: FnMut(char) -> bool> Pat<'a> for F { type S = PredS<'a, F>; fn into_s(self, h: &'a str) -> PredS<'a, F> { PredS { f: self, h, pos: 3 } } }
pub struct W<'a, P: Pat<'a>>(P::S);
pub enum E<'a, P: Pat<'a>> { One(P::S), Zero }
fn ctor<'a, P: Pat<'a>>(p: P, h: &'a str) -> W<'a, P> { W(p.into_s(h)) }
fn reified<'a, P: Pat<'a>>(p: P, h: &'a str) -> W<'a, P> { let c = W::<'a, P>; c(p.into_s(h)) }
fn variant<'a, P: Pat<'a>>(p: P, h: &'a str) -> E<'a, P> { E::One(p.into_s(h)) }
#[test]
fn ctor_with_projection_arg() {
let w = ctor(|c: char| c == '.', "a-b.c d");
assert_eq!(w.0.hay(), "a-b.c d");
assert_eq!(w.0.pos(), 3);
}
#[test]
fn reified_ctor_with_projection_arg() {
let w = reified(|c: char| c == 'b', "xyz");
assert_eq!(w.0.hay(), "xyz");
assert_eq!(w.0.pos(), 3);
}
#[test]
fn variant_ctor_with_projection_arg() {
match variant(|c: char| c == 'b', "hello") {
E::One(s) => assert_eq!((s.hay(), s.pos()), ("hello", 3)),
E::Zero => panic!("wrong variant"),
}
}
#[test]
fn str_replace_and_match_indices_with_closure() {
let key = "a-b.c d";
assert_eq!(key.replace(|c: char| !c.is_ascii_alphanumeric(), "_"), "a_b_c_d");
assert_eq!(key.replace(char::is_whitespace, "_"), "a-b.c_d");
let v: Vec<(usize, &str)> = key.match_indices(|c: char| c == '.').collect();
assert_eq!(v, vec![(3, ".")]);
}