1#[cxx::bridge(namespace = "klotski::ffi")]
2mod ffi {
3 #[derive(Debug)]
4 struct RsLayout {
5 code: u64
6 }
7
8 #[derive(Debug)]
9 struct RsShortCode {
10 code: u32
11 }
12
13 unsafe extern "C++" {
14 include!("rust_ffi/include/layout.h");
15
16 fn layout_check(val: u64) -> bool;
18
19 fn layout_from_str(s: &str) -> u64;
21
22 fn to_string(self: &RsLayout) -> String;
24
25 fn to_shorten_string(self: &RsLayout) -> String;
27
28 fn to_short_code(self: &RsLayout) -> RsShortCode;
30
31 fn is_vertical_mirror(self: &RsLayout) -> bool;
33
34 fn is_horizontal_mirror(self: &RsLayout) -> bool;
36
37 fn to_vertical_mirror(self: &RsLayout) -> RsLayout;
39
40 fn to_horizontal_mirror(self: &RsLayout) -> RsLayout;
42
43 fn n_1x1(self: &RsLayout) -> u8;
45
46 fn n_1x2(self: &RsLayout) -> u8;
48
49 fn n_2x1(self: &RsLayout) -> u8;
51
52 fn n_2x2(self: &RsLayout) -> u8;
54
55 fn type_id(self: &RsLayout) -> u8;
57
58 fn pattern_id(self: &RsLayout) -> u16;
60
61 fn toward_char(self: &RsLayout) -> u8;
65
66 fn case_id(self: &RsLayout) -> u32;
68
69 fn next_cases(self: &RsLayout) -> Vec<RsLayout>;
71 }
72
73 unsafe extern "C++" {
74 include!("rust_ffi/include/short_code.h");
75
76 fn short_code_check(val: u32) -> bool;
78
79 fn short_code_from_str(s: &str) -> u32;
81
82 fn to_string(self: &RsShortCode) -> String;
84
85 fn to_layout(self: &RsShortCode) -> RsLayout;
87
88 fn short_code_speed_up(fast_mode: bool);
90 }
91}
92
93pub use ffi::RsLayout as Layout;
94pub use ffi::RsShortCode as ShortCode;
95
96impl Layout {
97 pub fn check(code: u64) -> bool {
99 ffi::layout_check(code)
100 }
101
102 pub fn unsafe_create(code: u64) -> Self {
104 Self { code }
105 }
106
107 pub fn create(code: u64) -> Option<Self> {
109 if Self::check(code) {
110 return Some(Self::unsafe_create(code));
111 }
112 None
113 }
114
115 pub fn unwrap(self: &Self) -> u64 {
117 self.code
118 }
119
120 pub fn from_string(s: &str) -> Option<Self> {
122 let val = ffi::layout_from_str(s);
123 if val < 0x10_FFFF_FFFF {
124 return Some(Self::unsafe_create(val));
125 }
126 None
127 }
128}
129
130impl ShortCode {
131 pub fn check(code: u32) -> bool {
133 ffi::short_code_check(code)
134 }
135
136 pub fn unsafe_create(code: u32) -> Self {
138 Self { code }
139 }
140
141 pub fn create(code: u32) -> Option<Self> {
143 if Self::check(code) {
144 return Some(Self::unsafe_create(code));
145 }
146 None
147 }
148
149 pub fn unwrap(self: &Self) -> u32 {
151 self.code
152 }
153
154 pub fn from_string(s: &str) -> Option<Self> {
156 let val = ffi::short_code_from_str(s);
157 if val != 0xFFFF_FFFF {
158 return Some(Self::unsafe_create(val));
159 }
160 None
161 }
162
163 pub fn speed_up(fast_mode: bool) {
164 ffi::short_code_speed_up(fast_mode)
165 }
166}
167
168impl PartialEq for Layout {
169 fn eq(&self, other: &Self) -> bool {
170 self.code == other.code
171 }
172}
173
174impl PartialEq for ShortCode {
175 fn eq(&self, other: &Self) -> bool {
176 self.code == other.code
177 }
178}