diff --git a/crates/backend/src/typegen.rs b/crates/backend/src/typegen.rs index 3f835ef1..81bd9108 100644 --- a/crates/backend/src/typegen.rs +++ b/crates/backend/src/typegen.rs @@ -180,6 +180,27 @@ static KNOWN_TYPES: Lazy> = Lazy::new(|| { ("Either3", "{} | {} | {}"), ("Either4", "{} | {} | {} | {}"), ("Either5", "{} | {} | {} | {} | {}"), + ("Either6", "{} | {} | {} | {} | {} | {}"), + ("Either7", "{} | {} | {} | {} | {} | {} | {}"), + ("Either8", "{} | {} | {} | {} | {} | {} | {} | {}"), + ("Either9", "{} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either10", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either11", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either12", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either13", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either14", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either15", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either16", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either17", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either18", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either19", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either20", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either21", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either22", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either23", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either24", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either25", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), + ("Either26", "{} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {} | {}"), ("Null", "null"), ("JsNull", "null"), ("null", "null"), diff --git a/crates/napi/src/bindgen_runtime/js_values/either.rs b/crates/napi/src/bindgen_runtime/js_values/either.rs index aab142b6..28ec5b4c 100644 --- a/crates/napi/src/bindgen_runtime/js_values/either.rs +++ b/crates/napi/src/bindgen_runtime/js_values/either.rs @@ -95,238 +95,108 @@ impl ToNapiValue for Either { } } -#[derive(Debug, Clone, Copy)] -pub enum Either3 { - A(A), - B(B), - C(C), -} +macro_rules! count_idents { + ( $( $idents:ident ),* $( , )* ) => { + { + #[allow(dead_code, non_camel_case_types)] + enum Idents { $( $idents, )* __LastVariant } + const COUNT: usize = Idents::__LastVariant as usize; -impl TypeName for Either3 { - fn type_name() -> &'static str { - "Either3" - } - - fn value_type() -> ValueType { - ValueType::Unknown - } -} - -impl - FromNapiValue for Either3 -{ - unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result { - debug_assert!( - { - let mut types = vec![A::value_type(), B::value_type(), C::value_type()]; - types.dedup(); - types.len() == 3 - }, - "{}", - ERROR_MSG - ); - let js_type = type_of!(env, napi_val)?; - if js_type == A::value_type() { - unsafe { A::from_napi_value(env, napi_val).map(Self::A) } - } else if js_type == B::value_type() { - unsafe { B::from_napi_value(env, napi_val).map(Self::B) } - } else if js_type == C::value_type() { - unsafe { C::from_napi_value(env, napi_val).map(Self::C) } - } else { - Err(crate::Error::new( - Status::InvalidArg, - format!( - "Expect type {} or {} or {}, but got {}", - A::value_type(), - B::value_type(), - C::value_type(), - js_type - ), - )) + COUNT } - } + }; } -impl ToNapiValue for Either3 { - unsafe fn to_napi_value( - env: sys::napi_env, - value: Self, - ) -> crate::Result { - match value { - Self::A(a) => unsafe { A::to_napi_value(env, a) }, - Self::B(b) => unsafe { B::to_napi_value(env, b) }, - Self::C(c) => unsafe { C::to_napi_value(env, c) }, +macro_rules! either_n { + ( $either_name:ident, $( $parameter:ident ),+ $( , )* ) => { + #[derive(Debug, Clone, Copy)] + pub enum $either_name< $( $parameter ),+ > { + $( $parameter ( $parameter ) ),+ } - } -} -#[derive(Debug, Clone, Copy)] -pub enum Either4 { - A(A), - B(B), - C(C), - D(D), -} + impl< $( $parameter ),+ > TypeName for $either_name < $( $parameter ),+ > + where $( $parameter: TypeName ),+ + { + fn type_name() -> &'static str { + stringify!( $either_name ) + } -impl TypeName for Either4 { - fn type_name() -> &'static str { - "Either4" - } - - fn value_type() -> ValueType { - ValueType::Unknown - } -} - -impl< - A: TypeName + FromNapiValue, - B: TypeName + FromNapiValue, - C: TypeName + FromNapiValue, - D: TypeName + FromNapiValue, - > FromNapiValue for Either4 -{ - unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result { - debug_assert!( - { - let mut types = vec![ - A::value_type(), - B::value_type(), - C::value_type(), - D::value_type(), - ]; - types.dedup(); - types.len() == 4 - }, - "{}", - ERROR_MSG - ); - let js_type = type_of!(env, napi_val)?; - if js_type == A::value_type() { - unsafe { A::from_napi_value(env, napi_val).map(Self::A) } - } else if js_type == B::value_type() { - unsafe { B::from_napi_value(env, napi_val).map(Self::B) } - } else if js_type == C::value_type() { - unsafe { C::from_napi_value(env, napi_val).map(Self::C) } - } else if js_type == D::value_type() { - unsafe { D::from_napi_value(env, napi_val).map(Self::D) } - } else { - Err(crate::Error::new( - Status::InvalidArg, - format!( - "Expect type {} or {} or {} or {}, but got {}", - A::value_type(), - B::value_type(), - C::value_type(), - D::value_type(), - js_type - ), - )) + fn value_type() -> ValueType { + ValueType::Unknown + } } - } -} -impl ToNapiValue - for Either4 -{ - unsafe fn to_napi_value( - env: sys::napi_env, - value: Self, - ) -> crate::Result { - match value { - Self::A(a) => unsafe { A::to_napi_value(env, a) }, - Self::B(b) => unsafe { B::to_napi_value(env, b) }, - Self::C(c) => unsafe { C::to_napi_value(env, c) }, - Self::D(d) => unsafe { D::to_napi_value(env, d) }, + impl< $( $parameter ),+ > FromNapiValue for $either_name < $( $parameter ),+ > + where $( $parameter: TypeName + FromNapiValue ),+ + { + unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result { + debug_assert!( + { + let mut types = vec![ $( $parameter ::value_type() ),+ ]; + types.dedup(); + + types.len() == count_idents!( $( $parameter ),+ ) + }, + "{}", + ERROR_MSG + ); + + let js_type = type_of!(env, napi_val)?; + + $( + if js_type == $parameter::value_type() { + unsafe { $parameter ::from_napi_value(env, napi_val).map(Self:: $parameter ) } + } else + )+ + { + Err(crate::Error::new( + Status::InvalidArg, + format!( + concat!("Expect type ", $( "`{", stringify!( $parameter ), "}`, " ),+ , "but got {js_type}"), + $( $parameter = $parameter::value_type(), )+ + js_type = js_type, + ), + )) + } + } } - } -} -#[derive(Debug, Clone, Copy)] -pub enum Either5 { - A(A), - B(B), - C(C), - D(D), - E(E), -} - -impl TypeName - for Either5 -{ - fn type_name() -> &'static str { - "Either5" - } - - fn value_type() -> ValueType { - ValueType::Unknown - } -} - -impl< - A: TypeName + FromNapiValue, - B: TypeName + FromNapiValue, - C: TypeName + FromNapiValue, - D: TypeName + FromNapiValue, - E: TypeName + FromNapiValue, - > FromNapiValue for Either5 -{ - unsafe fn from_napi_value(env: sys::napi_env, napi_val: sys::napi_value) -> crate::Result { - debug_assert!( - { - let mut types = vec![ - A::value_type(), - B::value_type(), - C::value_type(), - D::value_type(), - E::value_type(), - ]; - types.dedup(); - types.len() == 5 - }, - "{}", - ERROR_MSG - ); - let js_type = type_of!(env, napi_val)?; - if js_type == A::value_type() { - unsafe { A::from_napi_value(env, napi_val).map(Self::A) } - } else if js_type == B::value_type() { - unsafe { B::from_napi_value(env, napi_val).map(Self::B) } - } else if js_type == C::value_type() { - unsafe { C::from_napi_value(env, napi_val).map(Self::C) } - } else if js_type == D::value_type() { - unsafe { D::from_napi_value(env, napi_val).map(Self::D) } - } else if js_type == E::value_type() { - unsafe { E::from_napi_value(env, napi_val).map(Self::E) } - } else { - Err(crate::Error::new( - Status::InvalidArg, - format!( - "Expect type {} or {} or {} or {} or {}, but got {}", - A::value_type(), - B::value_type(), - C::value_type(), - D::value_type(), - E::value_type(), - js_type - ), - )) + impl< $( $parameter ),+ > ToNapiValue for $either_name < $( $parameter ),+ > + where $( $parameter: ToNapiValue ),+ + { + unsafe fn to_napi_value( + env: sys::napi_env, + value: Self + ) -> crate::Result { + match value { + $( Self:: $parameter (v) => unsafe { $parameter ::to_napi_value(env, v) } ),+ + } + } } - } + }; } -impl ToNapiValue - for Either5 -{ - unsafe fn to_napi_value( - env: sys::napi_env, - value: Self, - ) -> crate::Result { - match value { - Self::A(a) => unsafe { A::to_napi_value(env, a) }, - Self::B(b) => unsafe { B::to_napi_value(env, b) }, - Self::C(c) => unsafe { C::to_napi_value(env, c) }, - Self::D(d) => unsafe { D::to_napi_value(env, d) }, - Self::E(e) => unsafe { E::to_napi_value(env, e) }, - } - } -} +either_n!(Either3, A, B, C); +either_n!(Either4, A, B, C, D); +either_n!(Either5, A, B, C, D, E); +either_n!(Either6, A, B, C, D, E, F); +either_n!(Either7, A, B, C, D, E, F, G); +either_n!(Either8, A, B, C, D, E, F, G, H); +either_n!(Either9, A, B, C, D, E, F, G, H, I); +either_n!(Either10, A, B, C, D, E, F, G, H, I, J); +either_n!(Either11, A, B, C, D, E, F, G, H, I, J, K); +either_n!(Either12, A, B, C, D, E, F, G, H, I, J, K, L); +either_n!(Either13, A, B, C, D, E, F, G, H, I, J, K, L, M); +either_n!(Either14, A, B, C, D, E, F, G, H, I, J, K, L, M, N); +either_n!(Either15, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O); +either_n!(Either16, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P); +either_n!(Either17, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q); +either_n!(Either18, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R); +either_n!(Either19, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S); +either_n!(Either20, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T); +either_n!(Either21, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U); +either_n!(Either22, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V); +either_n!(Either23, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W); +either_n!(Either24, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X); +either_n!(Either25, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y); +either_n!(Either26, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z);