1macro_rules! wand_common {
17 ( $wand:ident,
18 $new_wand:ident, $clear_wand:ident, $is_wand:ident, $clone:ident, $destroy:ident,
19 $clear_exc:ident, $get_exc_type:ident, $get_exc:ident
20 ) => {
21 pub struct $wand {
22 wand: *mut crate::bindings::$wand,
23 }
24
25 impl Default for $wand {
26 fn default() -> Self {
27 Self::new()
28 }
29 }
30
31 impl $wand {
32 pub fn new() -> Self {
33 $wand {
34 wand: unsafe { crate::bindings::$new_wand() },
35 }
36 }
37
38 pub (crate) fn from_ptr(ptr: *mut crate::bindings::$wand) -> Self {
39 $wand {
40 wand: ptr
41 }
42 }
43
44 pub (crate) fn as_ptr(&self) -> *mut crate::bindings::$wand {
45 self.wand
46 }
47
48 fn clear(&mut self) {
49 unsafe { crate::bindings::$clear_wand(self.wand) }
50 }
51
52 pub fn clear_exception(&mut self) -> Result<()> {
53 match unsafe { crate::bindings::$clear_exc(self.wand) } {
54 crate::bindings::MagickBooleanType::MagickTrue => Ok(()),
55 _ => Err(MagickError(
56 concat!("failed to clear", stringify!($wand), "exception").to_string(),
57 )),
58 }
59 }
60
61 pub fn get_exception_type(&self) -> crate::bindings::ExceptionType {
62 unsafe { crate::bindings::$get_exc_type(self.wand) }
63 }
64
65 pub fn get_exception(&self) -> Result<(String, crate::bindings::ExceptionType)> {
66 let mut severity: crate::bindings::ExceptionType =
67 crate::bindings::ExceptionType::UndefinedException;
68
69 let ptr = unsafe { crate::bindings::$get_exc(self.wand, &mut severity as *mut _) };
70 if ptr.is_null() {
71 Err(MagickError(
72 concat!("null ptr returned by", stringify!($wand), "get_exception")
73 .to_string(),
74 ))
75 } else {
76 let c_str = unsafe { CStr::from_ptr(ptr) };
77 let exception = c_str.to_string_lossy().into_owned();
78 unsafe { crate::bindings::RelinquishMagickMemory(ptr as *mut ::libc::c_void) };
79 Ok((exception, severity))
80 }
81 }
82
83 pub fn is_wand(&self) -> Result<()> {
84 match unsafe { crate::bindings::$is_wand(self.wand) } {
85 crate::bindings::MagickBooleanType::MagickTrue => Ok(()),
86 _ => Err(MagickError(
87 concat!(stringify!($wand), " not a wand").to_string(),
88 )),
89 }
90 }
91 }
92
93 impl Clone for $wand {
94 fn clone(&self) -> Self {
95 $wand {
96 wand: unsafe { crate::bindings::$clone(self.wand) },
97 }
98 }
99 }
100
101 impl Drop for $wand {
102 fn drop(&mut self) {
103 unsafe {
104 crate::bindings::$clear_exc(self.wand);
105 crate::bindings::$destroy(self.wand);
106 }
107 }
108 }
109
110 unsafe impl Send for $wand {}
112
113 };
117}
118
119macro_rules! get {
120 ($($get:ident, $c_get:ident, $typ:ty )*) => {
121 $(
122 pub fn $get(&self) -> $typ {
123 unsafe { crate::bindings::$c_get(self.wand).into() }
124 }
125 )*
126 }
127}
128
129macro_rules! set_get {
130 ($($get:ident, $set:ident, $c_get:ident, $c_set:ident, $typ:ty )*) => {
131 $(
132 pub fn $get(&self) -> $typ {
133 unsafe { crate::bindings::$c_get(self.wand).into() }
134 }
135 pub fn $set(&mut self, v: $typ) -> Result<()> {
136 match unsafe { crate::bindings::$c_set(self.wand, v.into()) } {
137 crate::bindings::MagickBooleanType::MagickTrue => Ok(()),
138 _ => Err(MagickError(concat!(stringify!($set), " returned false").to_string()))
139 }
140 }
141 )*
142 pub fn fmt_checked_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result {
143 $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())?; )*
144 Ok(())
145 }
146 }
147}
148
149macro_rules! set_get_unchecked {
150 ($($get:ident, $set:ident, $c_get:ident, $c_set:ident, $typ:ty )*) => {
151 $(
152 pub fn $get(&self) -> $typ {
153 unsafe { crate::bindings::$c_get(self.wand).into() }
154 }
155 pub fn $set(&mut self, v: $typ) {
156 unsafe { crate::bindings::$c_set(self.wand, v.into()) }
157 }
158 )*
159 pub fn fmt_unchecked_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result {
160 $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())?; )*
161 Ok(())
162 }
163 }
164}
165
166macro_rules! string_get {
167 ($get:ident, $c_get:ident) => {
168 pub fn $get(&self) -> Result<String> {
169 let ptr = unsafe { crate::bindings::$c_get(self.wand) };
170 if ptr.is_null() {
171 Err(MagickError(
172 concat!("null ptr returned by ", stringify!($get)).to_string(),
173 ))
174 } else {
175 let c_str = unsafe { ::std::ffi::CStr::from_ptr(ptr) };
176 let result: String = c_str.to_string_lossy().into_owned();
177 unsafe { crate::bindings::free(ptr as *mut ::libc::c_void) };
178 Ok(result)
179 }
180 }
181 };
182}
183
184macro_rules! string_set_get {
185 ($($get:ident, $set:ident, $c_get:ident, $c_set:ident)*) => {
186 $(
187 string_get!($get, $c_get);
188 pub fn $set(&mut self, s: &str) -> Result<()> {
189 let c_string = std::ffi::CString::new(s).map_err(|_| "could not convert to cstring")?;
190 match unsafe { crate::bindings::$c_set(self.wand, c_string.as_ptr()) } {
191 crate::bindings::MagickBooleanType::MagickTrue => Ok(()),
192 _ => Err(MagickError(concat!(stringify!($set), " returned false").to_string()))
193 }
194 }
195 )*
196 pub fn fmt_string_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result {
197 $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())?; )*
198 Ok(())
199 }
200 }
201}
202
203macro_rules! string_set_get_unchecked {
204 ($($get:ident, $set:ident, $c_get:ident, $c_set:ident )*) => {
205 $(
206 string_get!($get, $c_get);
207 pub fn $set(&mut self, s: &str) -> Result<()> {
208 let c_string = ::std::ffi::CString::new(s).map_err(|_| "could not convert to cstring")?;
209 unsafe { crate::bindings::$c_set(self.wand, c_string.as_ptr()) };
210 Ok(())
211 }
212 )*
213 pub fn fmt_string_unchecked_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result {
214 $( writeln!(f, "{}{:<50}: {:?}", prefix, stringify!($c_get), self.$get())?; )*
215 Ok(())
216 }
217 }
218}
219
220macro_rules! pixel_set_get {
221 ($($get:ident, $set:ident, $c_get:ident, $c_set:ident )*) => {
222 $(
223 pub fn $get(&self) -> crate::PixelWand {
224 let pw = crate::PixelWand::new();
225 unsafe { crate::bindings::$c_get(self.wand, pw.as_ptr()) };
226 pw
227 }
228 pub fn $set(&mut self, pw: &crate::PixelWand) {
229 unsafe { crate::bindings::$c_set(self.wand, pw.as_ptr()) }
230 }
231 )*
232 pub fn fmt_pixel_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result {
233 $(
234 writeln!(f, "{}{:<50}: ", prefix, stringify!($c_get))?;
235 self.$get().fmt_w_prefix(f, &format!("{}{:<53}", prefix, " ") )?;
236 )*
237 Ok(())
238 }
239 }
240}
241
242macro_rules! color_set_get {
243 ($(
244 $get:ident, $get_quantum:ident, $set:ident, $set_quantum:ident,
245 $c_get:ident, $c_get_quantum:ident, $c_set:ident, $c_set_quantum:ident
246 )*) => {
247 $(
248 pub fn $get(&self) -> f64 {
249 unsafe { crate::bindings::$c_get(self.wand) }
250 }
251 pub fn $get_quantum(&self) -> bindings::Quantum {
252 unsafe { crate::bindings::$c_get_quantum(self.wand) }
253 }
254 pub fn $set(&mut self, v: f64) {
255 unsafe { crate::bindings::$c_set(self.wand, v) }
256 }
257 pub fn $set_quantum(&mut self, v: bindings::Quantum) {
258 unsafe { crate::bindings::$c_set_quantum(self.wand, v) }
259 }
260 )*
261 pub fn fmt_color_settings(&self, f: &mut ::std::fmt::Formatter, prefix: &str) -> ::std::fmt::Result {
262 writeln!(f, "{}Color: {:?}, normalized: {:?}\n{}hsl: {:?}",
263 prefix,
264 self.get_color_as_string(),
265 self.get_color_as_normalized_string(),
266 prefix,
267 self.get_hsl()
268 )?;
269 $( writeln!(f, "{}{:<10}: {:>} quantum: {}", prefix, stringify!($c_get).split_at(8).1, self.$get(), self.$get_quantum())?; )*
270 Ok(())
271 }
272 }
273}
274
275macro_rules! mutations {
276 ($($(#[$attr:meta])* $c_fun:ident => $fun:ident($($arg:ident: $ty:ty),*))*) => {
277 $(
278 $(#[$attr])*
279 pub fn $fun(&self $(, $arg: $ty)*) -> Result<()> {
280 match unsafe { bindings::$c_fun(self.wand $(, $arg.into())*) } {
281 bindings::MagickBooleanType::MagickTrue => Ok(()),
282 _ => Err(MagickError(concat!(stringify!($c_fun), " invocation failed").to_string()))
283 }
284 }
285 )*
286 }
287}