timecat 1.52.0

A NNUE-based chess engine that implements the Negamax algorithm and can be integrated into any project as a library. It features move generation, advanced position evaluation through NNUE, and move searching capabilities.
Documentation
#[cfg(feature = "serde")]
mod serde_tests {
    use timecat::*;

    fn test_serde<T>(data: T) -> std::result::Result<(), Box<dyn Error>>
    where
        T: Serialize + for<'de> Deserialize<'de> + Debug + PartialEq,
    {
        let json = serde_json::to_string(&data)?;
        let de_data: T = serde_json::from_str(&json)?;
        assert_eq!(data, de_data);
        Ok(())
    }

    macro_rules! test_serde_wrapper {
        ($func_name: ident, $data: expr) => {
            #[test]
            fn $func_name() -> std::result::Result<(), Box<dyn Error>> {
                test_serde(SerdeWrapper::new($data))
            }
        };
    }

    macro_rules! test_serde_wrapper_empty_array {
        ($func_name: ident, $type: ty) => {
            #[test]
            fn $func_name() -> std::result::Result<(), Box<dyn Error>> {
                let empty_array: [$type; _] = [];
                test_serde(SerdeWrapper::new(empty_array))
            }
        };
    }

    test_serde_wrapper!(serde_wrapper_test_1, [1, 2, 3, 4, 5]);
    test_serde_wrapper!(serde_wrapper_test_2, [1, 2, 3, 4, 5].map(|i| i.to_string()));

    test_serde_wrapper_empty_array!(serde_wrapper_empty_array_test_1, i32);
    test_serde_wrapper_empty_array!(serde_wrapper_empty_array_test_2, String);
    test_serde_wrapper_empty_array!(serde_wrapper_empty_array_test_3, Vec<String>);

    #[test]
    fn serde_wrapper_empty_array_test_str_1() -> std::result::Result<(), Box<dyn Error>> {
        let data: SerdeWrapper<[&str; _]> = SerdeWrapper::new([]);
        let json = serde_json::to_string(&data)?;
        let de_data: SerdeWrapper<[&str; _]> = serde_json::from_str(&json)?;
        assert_eq!(data, de_data);
        Ok(())
    }

    #[test]
    fn serde_wrapper_empty_array_test_str_2() -> std::result::Result<(), Box<dyn Error>> {
        let data: SerdeWrapper<[&str; 2]> = SerdeWrapper::new(["foo", "bar"]);
        let json = serde_json::to_string(&data)?;
        let de_data: SerdeWrapper<[&str; 2]> = serde_json::from_str(&json)?;
        assert_eq!(data, de_data);
        Ok(())
    }
}