smelt_stdlib/fields.rs
1//! Exact source field-name recognition metadata shared by frontends and codegen.
2
3/// Field read whose semantics come from the standard library rather than a
4/// user-defined type shape.
5#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
6#[non_exhaustive]
7pub enum FieldRule {
8 /// JavaScript `.length` on string/array-shaped receivers.
9 TsLength,
10 /// JavaScript `.constructor`, which Smelt erases to a null value.
11 TsConstructor,
12 /// JavaScript `.sort` read as a bound array method on erased receivers.
13 TsSort,
14}
15
16/// Return the shared field rule for an exact TypeScript field spelling.
17///
18/// Callers stay responsible for receiver-shape checks; this only resolves the
19/// stdlib identity of the field name itself.
20#[must_use]
21pub fn typescript_field_rule(field: &str) -> Option<FieldRule> {
22 match field {
23 "length" => Some(FieldRule::TsLength),
24 "constructor" => Some(FieldRule::TsConstructor),
25 "sort" => Some(FieldRule::TsSort),
26 _ => None,
27 }
28}
29
30#[cfg(test)]
31mod tests {
32 use super::*;
33
34 /// Exact stdlib field spellings resolve to their registry identity.
35 #[test]
36 fn recognizes_stdlib_field_names() {
37 assert_eq!(typescript_field_rule("length"), Some(FieldRule::TsLength));
38 assert_eq!(
39 typescript_field_rule("constructor"),
40 Some(FieldRule::TsConstructor)
41 );
42 assert_eq!(typescript_field_rule("sort"), Some(FieldRule::TsSort));
43 }
44
45 /// Ordinary user field names never resolve to a stdlib rule.
46 #[test]
47 fn rejects_user_field_names() {
48 for field in ["len", "lengthInMeters", "construct", "sorted", "value"] {
49 assert_eq!(typescript_field_rule(field), None);
50 }
51 }
52}