use crate::common::{CombinedSeq, NoOp, NoOpSeq, SingularSeq, Str, StrArrSeq};
use crate::context::{EmptyContext, SingularContext};
use crate::rust::{
AnonTuple, ArrayFromElements, ArrayInit, AssociatedItem, BoundedTypeVar, CanHaveAttributes,
Cfg, Dereference, Edition, FunctionBodyDeclare, FunctionDef, FunctionParam, MemberAccess,
ModPub, ModUnsafe, ModUnsafeExtern, MustUse, NamedTuple, NoMangle, Parameterized, RefOf,
Target, TraitImpl, Turbofish, TypeAsTrait, UseType,
};
use crate::util::InMemoryOutput;
#[test]
fn edition_order() {
assert!(Edition::Rust2018 < Edition::Rust2021);
assert!(Edition::Rust2018 < Edition::Rust2024);
}
#[test]
fn use_type() {
let string =
InMemoryOutput::print_output(EmptyContext, &UseType(Str("crate::common::NoOpSeq")));
assert_eq!("use crate::common::NoOpSeq;\n", string)
}
#[test]
fn type_as_trait_associated_item() {
let string = InMemoryOutput::print_output(
EmptyContext,
&AssociatedItem(TypeAsTrait(Str("E"), Str("MyTrait")), Str("AssocItem")),
);
assert_eq!("<E as MyTrait>::AssocItem", string);
}
#[test]
fn conditional_function_on_wasm() {
let string = InMemoryOutput::print_output(
EmptyContext,
&FunctionDef {
mods: CombinedSeq(SingularSeq(ModPub), SingularSeq(ModUnsafeExtern(Str("C")))),
name: Str("incoming"),
args: SingularSeq(FunctionParam(Str("data"), Str("u16"))),
return_type: Str("()"),
where_conds: NoOpSeq,
body: FunctionBodyDeclare,
}
.with_attributes(SingularSeq(Cfg(Target::Family(Str("wasm"))))),
);
assert_eq!(
"#[cfg(target_family = \"wasm\")]\npub unsafe extern \"C\" fn incoming(data: u16) -> ();\n\n",
string
);
}
#[test]
fn function_with_attributes_on_params() {
let string =
InMemoryOutput::print_output(
EmptyContext,
&FunctionDef {
mods: NoOpSeq,
name: Str("hello_world"),
args: CombinedSeq(
SingularSeq(FunctionParam(Str("var1"), Str("Type")).with_attributes(
CombinedSeq(SingularSeq(MustUse), SingularSeq(Str("attr2"))),
)),
SingularSeq(FunctionParam(Str("var2"), Str("&'static Type2"))),
),
return_type: Str("()"),
where_conds: NoOpSeq,
body: FunctionBodyDeclare,
},
);
assert_eq!(
"fn hello_world(#[must_use] #[attr2] var1: Type, var2: &'static Type2) -> ();\n\n",
string
);
}
#[test]
fn turbofish() {
let string = InMemoryOutput::print_output(
EmptyContext,
&Turbofish(Str("my_method"), StrArrSeq(&["V1", "V2"])),
);
assert_eq!("my_method::<V1, V2>", string);
let string = InMemoryOutput::print_output(EmptyContext, &Turbofish(Str("my_method"), NoOpSeq));
assert_eq!("my_method", string);
}
#[test]
fn array_from_elements() {
let string = InMemoryOutput::print_output(
EmptyContext,
&ArrayFromElements(StrArrSeq(&["1", "2", "-4"])),
);
assert_eq!("[1, 2, -4]", string);
}
#[test]
fn no_mangle_attr_2021() {
let string = InMemoryOutput::print_output(SingularContext(Edition::Rust2021), &NoMangle);
assert_eq!(string, "no_mangle");
}
#[test]
fn no_mangle_attr_2024() {
let string = InMemoryOutput::print_output(SingularContext(Edition::Rust2024), &NoMangle);
assert_eq!(string, "unsafe(no_mangle)");
}
#[test]
fn dereference_raw_ptr_field() {
let string = InMemoryOutput::print_output(
EmptyContext,
&RefOf(Dereference(MemberAccess(Str("my_struct"), Str("my_ptr")))),
);
assert_eq!("&*my_struct.my_ptr", string);
}
#[test]
fn array_init() {
let array_init = ArrayInit(Str("None"), Str("5"));
let string = InMemoryOutput::print_output(EmptyContext, &array_init);
assert_eq!("[None; 5]", string);
}
#[test]
fn trait_with_unsafe_impl() {
let trait_impl = TraitImpl {
mods: SingularSeq(ModUnsafe),
type_variables: SingularSeq(Str("T")),
the_trait: Str("Debug"),
receiver: Parameterized(Str("MyType"), SingularSeq(Str("T"))),
where_conds: NoOpSeq,
body: NoOp,
};
let string = InMemoryOutput::print_output(EmptyContext, &trait_impl);
assert_eq!(string, "unsafe impl<T> Debug for MyType<T> {\n}\n\n");
}
#[test]
fn named_tuple() {
let string = InMemoryOutput::print_output(
EmptyContext,
&NamedTuple {
name: Str("MyType"),
args: StrArrSeq(&["V1", "V2"]),
},
);
assert_eq!(string, "MyType(V1, V2)");
let string = InMemoryOutput::print_output(
EmptyContext,
&NamedTuple {
name: Str("MyType"),
args: NoOpSeq,
},
);
assert_eq!(string, "MyType");
}
#[test]
fn anon_tuple() {
let string = InMemoryOutput::print_output(EmptyContext, &AnonTuple(StrArrSeq(&["V1", "V2"])));
assert_eq!(string, "(V1, V2)");
let string = InMemoryOutput::print_output(EmptyContext, &AnonTuple(NoOpSeq));
assert_eq!(string, "()");
}
#[test]
fn bounded_type_var() {
let type_var = BoundedTypeVar(
Str("MyType"),
CombinedSeq(SingularSeq(Str("B1")), SingularSeq(Str("B2"))),
);
let string = InMemoryOutput::print_output(EmptyContext, &type_var);
assert_eq!(string, "MyType: B1 + B2");
}