Refactored nested match expressions for TS parser. (#3955)

* Refactored nested match expressions into inline pattern matching with early returns for improved readability and reduced nesting

* Updated fn naming, map_while instead of filter_map fix

---------

Co-authored-by: HugoCasa <hugo@casademont.ch>
This commit is contained in:
Dominik Polzer
2024-07-16 14:22:38 +02:00
committed by GitHub
co-authored by HugoCasa
parent ae178cdaeb
commit d9dba62165
+39 -65
View File
@@ -403,71 +403,9 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
} else {
if types.len() > 1 {
let one_of_values: Vec<OneOfVariant> = types
.into_iter()
.map_while(|x| match &**x {
TsType::TsTypeLit(TsTypeLit { members, .. }) => {
let label = members
.iter()
.find_map(|y| match y {
TsTypeElement::TsPropertySignature(
TsPropertySignature { key, type_ann, .. },
) => match (&**key, type_ann) {
(Expr::Ident(Ident { sym, .. }), type_ann) => {
if sym.to_string() == "label" {
type_ann.as_ref().map(|z| match &*z.type_ann {
TsType::TsLitType(TsLitType {
lit: TsLit::Str(Str { value, .. }),
..
}) => Some(value.to_string()),
_ => None,
})
} else {
None
}
}
_ => None,
},
_ => None,
})
.flatten();
match label {
Some(label) => {
let properties: Vec<ObjectProperty> = members
.into_iter()
.filter_map(|x| match x {
TsTypeElement::TsPropertySignature(
TsPropertySignature { key, type_ann, .. },
) => match (*key.to_owned(), type_ann) {
(Expr::Ident(Ident { sym, .. }), type_ann) => {
Some(ObjectProperty {
key: sym.to_string(),
typ: type_ann
.as_ref()
.map(|typ| {
Box::new(
tstype_to_typ(
&*typ.type_ann,
)
.0,
)
})
.unwrap_or(Box::new(Typ::Unknown)),
})
}
_ => None,
},
_ => None,
})
.collect();
Some(OneOfVariant { label, properties })
}
_ => None,
}
}
_ => None,
})
.collect();
.into_iter()
.map_while(parse_one_of_type)
.collect();
if one_of_values.len() == types.len() {
return (Typ::OneOf(one_of_values), false);
@@ -533,6 +471,42 @@ fn tstype_to_typ(ts_type: &TsType) -> (Typ, bool) {
}
}
fn parse_one_of_type(x: &Box<TsType>) -> Option<OneOfVariant> {
match &**x {
TsType::TsTypeLit(TsTypeLit { members, .. }) => {
let label = one_of_label(members)?;
let properties = one_of_properties(members);
Some(OneOfVariant { label, properties })
}
_ => None,
}
}
fn one_of_label(members: &Vec<TsTypeElement>) -> Option<String> {
members.iter().find_map(|y| {
let TsTypeElement::TsPropertySignature(TsPropertySignature { key, type_ann, .. }) = y else { return None; };
let Expr::Ident(Ident { sym, .. }) = &**key else { return None; };
if sym != "label" { return None; }
let Some(type_ann) = type_ann.as_ref() else { return None; };
let TsType::TsLitType(TsLitType { lit: TsLit::Str(Str { value, .. }), .. }) = &*type_ann.type_ann else { return None; };
Some(value.to_string())
})
}
fn one_of_properties(members: &Vec<TsTypeElement>) -> Vec<ObjectProperty> {
members.iter().filter_map(|x| {
let TsTypeElement::TsPropertySignature(TsPropertySignature { key, type_ann, .. }) = x else { return None; };
let Expr::Ident(Ident { sym, .. }) = *key.to_owned() else { return None; };
let typ = type_ann.as_ref().map(|typ| Box::new(tstype_to_typ(&*typ.type_ann).0)).unwrap_or(Box::new(Typ::Unknown));
Some(ObjectProperty { key: sym.to_string(), typ })
}).collect()
}
fn find_undefined(types: &Vec<Box<TsType>>) -> Option<usize> {
types.into_iter().position(|x| match **x {
TsType::TsKeywordType(TsKeywordType { kind, .. }) => {