#![feature(min_specialization)] use specialized_dispatch::specialized_dispatch; #[test] fn test_example() { fn example(expr: E) -> String { specialized_dispatch!( E -> String, default fn (_: T) => format!("default value"), fn (v: u8) => format!("u8: {}", v), fn (v: u16) => format!("u16: {}", v), expr, ) } assert_eq!(example(1.0), "default value"); assert_eq!(example(5u8), "u8: 5"); assert_eq!(example(10u16), "u16: 10"); } #[test] fn test_example_different_order() { fn example(expr: E) -> String { specialized_dispatch!( E -> String, fn (v: u8) => format!("u8: {}", v), fn (v: u16) => format!("u16: {}", v), default fn (_: T) => format!("default value"), expr, ) } assert_eq!(example(1.0), "default value"); assert_eq!(example(5u8), "u8: 5"); assert_eq!(example(10u16), "u16: 10"); } #[test] fn test_multiple_calls_in_same_scope() { let s1 = specialized_dispatch!( u8 -> &'static str, fn (_: u8) => "u8", fn (_: u16) => "u16", default fn (_: T) => "other", 0u8, ); let s2 = specialized_dispatch!( u16 -> &'static str, fn (_: u8) => "u8", fn (_: u16) => "u16", default fn (_: T) => "other", 0u16, ); assert_eq!(format!("{}-{}", s1, s2), "u8-u16"); } #[test] fn test_bound_traits() { use std::fmt::{Debug, Display}; fn example(expr: E) -> String { specialized_dispatch!( E -> String, default fn (v: T) => format!("default value: {}", v), fn (v: u8) => format!("u8: {}", v), fn (v: u16) => format!("u16: {}", v), expr, ) } assert_eq!(example(1.5), "default value: 1.5"); assert_eq!(example(5u8), "u8: 5"); assert_eq!(example(10u16), "u16: 10"); } #[test] fn test_bound_traits_with_generic() { use std::fmt::Display; trait GenericTrait {} impl GenericTrait<()> for f32 {} impl GenericTrait<()> for u8 {} impl GenericTrait<()> for u16 {} fn example>(expr: E) -> String { specialized_dispatch!( E -> String, default fn >(v: T) => format!("default value: {}", v), fn (v: u8) => format!("u8: {}", v), fn (v: u16) => format!("u16: {}", v), expr, ) } assert_eq!(example(1.5), "default value: 1.5"); assert_eq!(example(5u8), "u8: 5"); assert_eq!(example(10u16), "u16: 10"); } #[test] fn test_extra_args() { use std::fmt::Display; fn example(expr: T, arg: u8) -> String { specialized_dispatch!( T -> String, default fn (v: T, arg: u8) => format!("default value: {}, arg: {}", v, arg), fn (v: u8, arg: u8) => format!("u8: {}, arg: {}", v, arg), fn (v: u16, arg: u8) => format!("u16: {}, arg: {}", v, arg), expr, arg, ) } assert_eq!(example(1.5, 123u8), "default value: 1.5, arg: 123"); assert_eq!(example(5u8, 12u8), "u8: 5, arg: 12"); assert_eq!(example(10u16, 1u8), "u16: 10, arg: 1"); } #[test] fn test_extra_args_with_str_arg() { use std::fmt::Display; fn example(expr: T, arg: &str) -> String { specialized_dispatch!( T -> String, default fn (v: T, arg: &str) => format!("default value: {}, arg: {}", v, arg), fn (v: u8, arg: &str) => format!("u8: {}, arg: {}", v, arg), fn (v: u16, arg: &str) => format!("u16: {}, arg: {}", v, arg), expr, arg, ) } assert_eq!(example(1.5, "ben bir"), "default value: 1.5, arg: ben bir"); assert_eq!(example(5u8, "ceviz"), "u8: 5, arg: ceviz"); assert_eq!(example(10u16, "agaciyim"), "u16: 10, arg: agaciyim"); }