1#![deny(clippy::unwrap_used)]
2#![deny(clippy::expect_used)]
3#![warn(clippy::pedantic)]
4#![warn(clippy::nursery)]
5#![allow(clippy::literal_string_with_formatting_args)]
6#![deny(clippy::unwrap_used, clippy::expect_used)]
7#![allow(clippy::must_use_candidate)]
8#![warn(missing_debug_implementations)]
9#![warn(missing_copy_implementations)]
10#![allow(clippy::module_name_repetitions)]
11#![warn(
12 clippy::arithmetic_side_effects,
13 clippy::unreachable,
14 clippy::unchecked_duration_subtraction,
15 clippy::todo,
16 clippy::string_slice,
17 clippy::panic_in_result_fn,
18 clippy::indexing_slicing,
19 clippy::panic,
20 clippy::exit,
21 clippy::as_conversions,
22 clippy::large_futures,
23 clippy::large_stack_arrays,
24 clippy::large_stack_frames,
25 clippy::modulo_one,
26 clippy::mem_replace_with_uninit,
27 clippy::iterator_step_by_zero,
28 clippy::invalid_regex,
29 clippy::print_stdout,
30 clippy::print_stderr
31)]
32#![doc = include_str!("../README.md")]
33
34mod visitor;
35
36dry_mods::mods! {
37 pub mod eco, date, round;
38 mod pub use
39 eco_category,
40 move_number,
41 outcome,
42 pgn,
43 raw_header_owned,
44 movetext;
45}
46
47pub use date::Date;
48pub use eco::Eco;
49pub use round::Round;
50
51#[doc(hidden)]
54pub mod samples;
55pub use movetext::Movetext;
56
57#[macro_export]
65macro_rules! variation {
66 (_turn: $san:literal) => {
67 $crate::movetext::SanWithVariations { san: ::shakmaty::san::SanPlus::from_ascii($san).unwrap(), variations: vec![] }
68 };
69 (_turn: ($san:literal, [$($vars:tt),+])) => {
70 $crate::movetext::SanWithVariations { san: ::shakmaty::san::SanPlus::from_ascii($san).unwrap(), variations: vec![$($crate::variation! $vars),+] }
71 };
72 {$($turn:tt),+} => {
73 $crate::movetext::Variation(vec![$($crate::variation!(_turn: $turn)),+])
74 };
75}
76
77#[macro_export]
82macro_rules! sans {
83 ($($san:literal),+) => {
84 $crate::movetext::Sans(vec![$(::shakmaty::san::SanPlus::from_ascii($san).unwrap()),+])
85 };
86}
87
88#[cfg(feature = "serde")]
89macro_rules! serde_display_from_str {
90 ($type:ident) => {
91 impl serde::Serialize for $type {
92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: serde::Serializer,
95 {
96 serializer.serialize_str(self.to_string().as_str())
97 }
98 }
99
100 impl<'de> serde::Deserialize<'de> for $type {
101 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
102 where
103 D: serde::Deserializer<'de>,
104 {
105 use serde::de::Error;
106 <&str>::deserialize(deserializer)?
107 .parse()
108 .map_err(D::Error::custom)
109 }
110 }
111 };
112
113 ($type:ident<$g:ident: Display + FromStr>) => {
114 impl<$g> serde::Serialize for $type<$g>
115 where
116 $g: std::fmt::Display + std::str::FromStr,
117 {
118 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
119 where
120 S: serde::Serializer,
121 {
122 serializer.serialize_str(self.to_string().as_str())
123 }
124 }
125
126 impl<'de, $g> serde::Deserialize<'de> for $type<$g>
127 where
128 $g: std::fmt::Display + std::str::FromStr,
129 {
130 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
131 where
132 D: serde::Deserializer<'de>,
133 {
134 <&str>::deserialize(deserializer)?
135 .parse()
136 .map_err(serde::de::Error::custom)
137 }
138 }
139 };
140}
141
142#[cfg(feature = "serde")]
143pub(crate) use serde_display_from_str;