glib/
enums.rs

1// Copyright 2015-2016, The Gtk-rs Project Developers.
2// See the COPYRIGHT file at the top-level directory of this distribution.
3// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
5use glib_sys;
6use gobject_sys;
7use std::cmp;
8use translate::*;
9use value::Value;
10use CStr;
11use Type;
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
14pub enum UserDirectory {
15    Desktop,
16    Documents,
17    Downloads,
18    Music,
19    Pictures,
20    PublicShare,
21    Templates,
22    Videos,
23    #[doc(hidden)]
24    NDirectories,
25}
26
27#[doc(hidden)]
28impl ToGlib for UserDirectory {
29    type GlibType = glib_sys::GUserDirectory;
30
31    fn to_glib(&self) -> glib_sys::GUserDirectory {
32        match *self {
33            UserDirectory::Desktop => glib_sys::G_USER_DIRECTORY_DESKTOP,
34            UserDirectory::Documents => glib_sys::G_USER_DIRECTORY_DOCUMENTS,
35            UserDirectory::Downloads => glib_sys::G_USER_DIRECTORY_DOWNLOAD,
36            UserDirectory::Music => glib_sys::G_USER_DIRECTORY_MUSIC,
37            UserDirectory::Pictures => glib_sys::G_USER_DIRECTORY_PICTURES,
38            UserDirectory::PublicShare => glib_sys::G_USER_DIRECTORY_PUBLIC_SHARE,
39            UserDirectory::Templates => glib_sys::G_USER_DIRECTORY_TEMPLATES,
40            UserDirectory::Videos => glib_sys::G_USER_DIRECTORY_VIDEOS,
41            UserDirectory::NDirectories => glib_sys::G_USER_N_DIRECTORIES,
42        }
43    }
44}
45
46/// Representation of an `enum` for dynamically, at runtime, querying the values of the enum and
47/// using them.
48#[derive(Debug)]
49pub struct EnumClass(*mut gobject_sys::GEnumClass);
50
51impl EnumClass {
52    /// Create a new `EnumClass` from a `Type`.
53    ///
54    /// Returns `None` if `type_` is not representing an enum.
55    pub fn new(type_: Type) -> Option<Self> {
56        unsafe {
57            let is_enum: bool = from_glib(gobject_sys::g_type_is_a(
58                type_.to_glib(),
59                gobject_sys::G_TYPE_ENUM,
60            ));
61            if !is_enum {
62                return None;
63            }
64
65            Some(EnumClass(
66                gobject_sys::g_type_class_ref(type_.to_glib()) as *mut _
67            ))
68        }
69    }
70
71    /// `Type` of the enum.
72    pub fn type_(&self) -> Type {
73        unsafe { from_glib((*self.0).g_type_class.g_type) }
74    }
75
76    /// Gets `EnumValue` by integer `value`, if existing.
77    ///
78    /// Returns `None` if the enum does not contain any value
79    /// with `value`.
80    pub fn get_value(&self, value: i32) -> Option<EnumValue> {
81        unsafe {
82            let v = gobject_sys::g_enum_get_value(self.0, value);
83            if v.is_null() {
84                None
85            } else {
86                Some(EnumValue(v, self.clone()))
87            }
88        }
89    }
90
91    /// Gets `EnumValue` by string name `name`, if existing.
92    ///
93    /// Returns `None` if the enum does not contain any value
94    /// with name `name`.
95    pub fn get_value_by_name(&self, name: &str) -> Option<EnumValue> {
96        unsafe {
97            let v = gobject_sys::g_enum_get_value_by_name(self.0, name.to_glib_none().0);
98            if v.is_null() {
99                None
100            } else {
101                Some(EnumValue(v, self.clone()))
102            }
103        }
104    }
105
106    /// Gets `EnumValue` by string nick `nick`, if existing.
107    ///
108    /// Returns `None` if the enum does not contain any value
109    /// with nick `nick`.
110    pub fn get_value_by_nick(&self, nick: &str) -> Option<EnumValue> {
111        unsafe {
112            let v = gobject_sys::g_enum_get_value_by_nick(self.0, nick.to_glib_none().0);
113            if v.is_null() {
114                None
115            } else {
116                Some(EnumValue(v, self.clone()))
117            }
118        }
119    }
120
121    /// Gets all `EnumValue` of this `EnumClass`.
122    pub fn get_values(&self) -> Vec<EnumValue> {
123        unsafe {
124            let n = (*self.0).n_values;
125            let mut res = Vec::with_capacity(n as usize);
126            for i in 0..(n as usize) {
127                res.push(EnumValue((*self.0).values.add(i), self.clone()))
128            }
129            res
130        }
131    }
132
133    /// Converts integer `value` to a `Value`, if part of the enum.
134    pub fn to_value(&self, value: i32) -> Option<Value> {
135        self.get_value(value).map(|v| v.to_value())
136    }
137
138    /// Converts string name `name` to a `Value`, if part of the enum.
139    pub fn to_value_by_name(&self, name: &str) -> Option<Value> {
140        self.get_value_by_name(name).map(|v| v.to_value())
141    }
142
143    /// Converts string nick `nick` to a `Value`, if part of the enum.
144    pub fn to_value_by_nick(&self, nick: &str) -> Option<Value> {
145        self.get_value_by_nick(nick).map(|v| v.to_value())
146    }
147}
148
149impl Drop for EnumClass {
150    fn drop(&mut self) {
151        unsafe {
152            gobject_sys::g_type_class_unref(self.0 as *mut _);
153        }
154    }
155}
156
157impl Clone for EnumClass {
158    fn clone(&self) -> Self {
159        unsafe { EnumClass(gobject_sys::g_type_class_ref(self.type_().to_glib()) as *mut _) }
160    }
161}
162
163/// Representation of a single enum value of an `EnumClass`.
164#[derive(Debug, Clone)]
165pub struct EnumValue(*const gobject_sys::GEnumValue, EnumClass);
166
167impl EnumValue {
168    /// Get integer value corresponding to the value.
169    pub fn get_value(&self) -> i32 {
170        unsafe { (*self.0).value }
171    }
172
173    /// Get name corresponding to the value.
174    pub fn get_name(&self) -> &str {
175        unsafe { CStr::from_ptr((*self.0).value_name).to_str().unwrap() }
176    }
177
178    /// Get nick corresponding to the value.
179    pub fn get_nick(&self) -> &str {
180        unsafe { CStr::from_ptr((*self.0).value_nick).to_str().unwrap() }
181    }
182
183    /// Convert enum value to a `Value`.
184    pub fn to_value(&self) -> Value {
185        unsafe {
186            let mut v = Value::from_type(self.1.type_());
187            gobject_sys::g_value_set_enum(v.to_glib_none_mut().0, (*self.0).value);
188            v
189        }
190    }
191
192    /// Convert enum value from a `Value`.
193    pub fn from_value(value: &Value) -> Option<EnumValue> {
194        unsafe {
195            let enum_class = EnumClass::new(value.type_());
196            enum_class
197                .and_then(|e| e.get_value(gobject_sys::g_value_get_enum(value.to_glib_none().0)))
198        }
199    }
200
201    /// Get `EnumClass` to which the enum value belongs.
202    pub fn get_class(&self) -> &EnumClass {
203        &self.1
204    }
205}
206
207impl PartialEq for EnumValue {
208    fn eq(&self, other: &Self) -> bool {
209        self.get_value().eq(&other.get_value())
210    }
211}
212
213impl Eq for EnumValue {}
214
215impl PartialOrd for EnumValue {
216    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
217        self.get_value().partial_cmp(&other.get_value())
218    }
219}
220
221impl Ord for EnumValue {
222    fn cmp(&self, other: &Self) -> cmp::Ordering {
223        self.get_value().cmp(&other.get_value())
224    }
225}
226
227/// Representation of a `flags` for dynamically, at runtime, querying the values of the enum and
228/// using them
229#[derive(Debug)]
230pub struct FlagsClass(*mut gobject_sys::GFlagsClass);
231
232impl FlagsClass {
233    /// Create a new `FlagsClass` from a `Type`
234    ///
235    /// Returns `None` if `type_` is not representing a flags type.
236    pub fn new(type_: Type) -> Option<Self> {
237        unsafe {
238            let is_flags: bool = from_glib(gobject_sys::g_type_is_a(
239                type_.to_glib(),
240                gobject_sys::G_TYPE_FLAGS,
241            ));
242            if !is_flags {
243                return None;
244            }
245
246            Some(FlagsClass(
247                gobject_sys::g_type_class_ref(type_.to_glib()) as *mut _
248            ))
249        }
250    }
251
252    /// `Type` of the flags.
253    pub fn type_(&self) -> Type {
254        unsafe { from_glib((*self.0).g_type_class.g_type) }
255    }
256
257    /// Gets `FlagsValue` by integer `value`, if existing.
258    ///
259    /// Returns `None` if the flags do not contain any value
260    /// with `value`.
261    pub fn get_value(&self, value: u32) -> Option<FlagsValue> {
262        unsafe {
263            let v = gobject_sys::g_flags_get_first_value(self.0, value);
264            if v.is_null() {
265                None
266            } else {
267                Some(FlagsValue(v, self.clone()))
268            }
269        }
270    }
271
272    /// Gets `FlagsValue` by string name `name`, if existing.
273    ///
274    /// Returns `None` if the flags do not contain any value
275    /// with name `name`.
276    pub fn get_value_by_name(&self, name: &str) -> Option<FlagsValue> {
277        unsafe {
278            let v = gobject_sys::g_flags_get_value_by_name(self.0, name.to_glib_none().0);
279            if v.is_null() {
280                None
281            } else {
282                Some(FlagsValue(v, self.clone()))
283            }
284        }
285    }
286
287    /// Gets `FlagsValue` by string nick `nick`, if existing.
288    ///
289    /// Returns `None` if the flags do not contain any value
290    /// with nick `nick`.
291    pub fn get_value_by_nick(&self, nick: &str) -> Option<FlagsValue> {
292        unsafe {
293            let v = gobject_sys::g_flags_get_value_by_nick(self.0, nick.to_glib_none().0);
294            if v.is_null() {
295                None
296            } else {
297                Some(FlagsValue(v, self.clone()))
298            }
299        }
300    }
301
302    /// Gets all `FlagsValue` of this `FlagsClass`.
303    pub fn get_values(&self) -> Vec<FlagsValue> {
304        unsafe {
305            let n = (*self.0).n_values;
306            let mut res = Vec::with_capacity(n as usize);
307            for i in 0..(n as usize) {
308                res.push(FlagsValue((*self.0).values.add(i), self.clone()))
309            }
310            res
311        }
312    }
313
314    /// Converts integer `value` to a `Value`, if part of the flags.
315    pub fn to_value(&self, value: u32) -> Option<Value> {
316        self.get_value(value).map(|v| v.to_value())
317    }
318
319    /// Converts string name `name` to a `Value`, if part of the flags.
320    pub fn to_value_by_name(&self, name: &str) -> Option<Value> {
321        self.get_value_by_name(name).map(|v| v.to_value())
322    }
323
324    /// Converts string nick `nick` to a `Value`, if part of the flags.
325    pub fn to_value_by_nick(&self, nick: &str) -> Option<Value> {
326        self.get_value_by_nick(nick).map(|v| v.to_value())
327    }
328
329    /// Checks if the flags corresponding to integer `f` is set in `value`.
330    pub fn is_set(&self, value: &Value, f: u32) -> bool {
331        unsafe {
332            if self.type_() != value.type_() {
333                return false;
334            }
335
336            let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
337            flags & f != 0
338        }
339    }
340
341    /// Checks if the flags corresponding to string name `name` is set in `value`.
342    pub fn is_set_by_name(&self, value: &Value, name: &str) -> bool {
343        unsafe {
344            if self.type_() != value.type_() {
345                return false;
346            }
347
348            if let Some(f) = self.get_value_by_name(name) {
349                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
350                flags & f.get_value() != 0
351            } else {
352                false
353            }
354        }
355    }
356
357    /// Checks if the flags corresponding to string nick `nick` is set in `value`.
358    pub fn is_set_by_nick(&self, value: &Value, nick: &str) -> bool {
359        unsafe {
360            if self.type_() != value.type_() {
361                return false;
362            }
363
364            if let Some(f) = self.get_value_by_nick(nick) {
365                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
366                flags & f.get_value() != 0
367            } else {
368                false
369            }
370        }
371    }
372
373    /// Sets flags value corresponding to integer `f` in `value`, if part of that flags. If the
374    /// flag is already set, it will succeed without doing any changes.
375    ///
376    /// Returns `Ok(value)` with the flag set if successful, or `Err(value)` with the original
377    /// value otherwise.
378    pub fn set(&self, mut value: Value, f: u32) -> Result<Value, Value> {
379        unsafe {
380            if self.type_() != value.type_() {
381                return Err(value);
382            }
383
384            if let Some(f) = self.get_value(f) {
385                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
386                gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, flags | f.get_value());
387                Ok(value)
388            } else {
389                Err(value)
390            }
391        }
392    }
393
394    /// Sets flags value corresponding to string name `name` in `value`, if part of that flags.
395    /// If the flag is already set, it will succeed without doing any changes.
396    ///
397    /// Returns `Ok(value)` with the flag set if successful, or `Err(value)` with the original
398    /// value otherwise.
399    pub fn set_by_name(&self, mut value: Value, name: &str) -> Result<Value, Value> {
400        unsafe {
401            if self.type_() != value.type_() {
402                return Err(value);
403            }
404
405            if let Some(f) = self.get_value_by_name(name) {
406                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
407                gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, flags | f.get_value());
408                Ok(value)
409            } else {
410                Err(value)
411            }
412        }
413    }
414
415    /// Sets flags value corresponding to string nick `nick` in `value`, if part of that flags.
416    /// If the flag is already set, it will succeed without doing any changes.
417    ///
418    /// Returns `Ok(value)` with the flag set if successful, or `Err(value)` with the original
419    /// value otherwise.
420    pub fn set_by_nick(&self, mut value: Value, nick: &str) -> Result<Value, Value> {
421        unsafe {
422            if self.type_() != value.type_() {
423                return Err(value);
424            }
425
426            if let Some(f) = self.get_value_by_nick(nick) {
427                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
428                gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, flags | f.get_value());
429                Ok(value)
430            } else {
431                Err(value)
432            }
433        }
434    }
435
436    /// Unsets flags value corresponding to integer `f` in `value`, if part of that flags.
437    /// If the flag is already unset, it will succeed without doing any changes.
438    ///
439    /// Returns `Ok(value)` with the flag unset if successful, or `Err(value)` with the original
440    /// value otherwise.
441    pub fn unset(&self, mut value: Value, f: u32) -> Result<Value, Value> {
442        unsafe {
443            if self.type_() != value.type_() {
444                return Err(value);
445            }
446
447            if let Some(f) = self.get_value(f) {
448                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
449                gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, flags & !f.get_value());
450                Ok(value)
451            } else {
452                Err(value)
453            }
454        }
455    }
456
457    /// Unsets flags value corresponding to string name `name` in `value`, if part of that flags.
458    /// If the flag is already unset, it will succeed without doing any changes.
459    ///
460    /// Returns `Ok(value)` with the flag unset if successful, or `Err(value)` with the original
461    /// value otherwise.
462    pub fn unset_by_name(&self, mut value: Value, name: &str) -> Result<Value, Value> {
463        unsafe {
464            if self.type_() != value.type_() {
465                return Err(value);
466            }
467
468            if let Some(f) = self.get_value_by_name(name) {
469                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
470                gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, flags & !f.get_value());
471                Ok(value)
472            } else {
473                Err(value)
474            }
475        }
476    }
477
478    /// Unsets flags value corresponding to string nick `nick` in `value`, if part of that flags.
479    /// If the flag is already unset, it will succeed without doing any changes.
480    ///
481    /// Returns `Ok(value)` with the flag unset if successful, or `Err(value)` with the original
482    /// value otherwise.
483    pub fn unset_by_nick(&self, mut value: Value, nick: &str) -> Result<Value, Value> {
484        unsafe {
485            if self.type_() != value.type_() {
486                return Err(value);
487            }
488
489            if let Some(f) = self.get_value_by_nick(nick) {
490                let flags = gobject_sys::g_value_get_flags(value.to_glib_none().0);
491                gobject_sys::g_value_set_flags(value.to_glib_none_mut().0, flags & !f.get_value());
492                Ok(value)
493            } else {
494                Err(value)
495            }
496        }
497    }
498
499    /// Returns a new `FlagsBuilder` for conveniently setting/unsetting flags
500    /// and building a `Value`.
501    pub fn builder(&self) -> FlagsBuilder {
502        FlagsBuilder::new(self)
503    }
504
505    /// Returns a new `FlagsBuilder` for conveniently setting/unsetting flags
506    /// and building a `Value`. The `Value` is initialized with `value`.
507    pub fn builder_with_value(&self, value: Value) -> Option<FlagsBuilder> {
508        if self.type_() != value.type_() {
509            return None;
510        }
511
512        Some(FlagsBuilder::new_with_value(self, value))
513    }
514}
515
516impl Drop for FlagsClass {
517    fn drop(&mut self) {
518        unsafe {
519            gobject_sys::g_type_class_unref(self.0 as *mut _);
520        }
521    }
522}
523
524impl Clone for FlagsClass {
525    fn clone(&self) -> Self {
526        unsafe { FlagsClass(gobject_sys::g_type_class_ref(self.type_().to_glib()) as *mut _) }
527    }
528}
529
530/// Representation of a single flags value of a `FlagsClass`.
531#[derive(Debug, Clone)]
532pub struct FlagsValue(*const gobject_sys::GFlagsValue, FlagsClass);
533
534impl FlagsValue {
535    /// Get integer value corresponding to the value.
536    pub fn get_value(&self) -> u32 {
537        unsafe { (*self.0).value }
538    }
539
540    /// Get name corresponding to the value.
541    pub fn get_name(&self) -> &str {
542        unsafe { CStr::from_ptr((*self.0).value_name).to_str().unwrap() }
543    }
544
545    /// Get nick corresponding to the value.
546    pub fn get_nick(&self) -> &str {
547        unsafe { CStr::from_ptr((*self.0).value_nick).to_str().unwrap() }
548    }
549
550    /// Convert flags value to a `Value`.
551    pub fn to_value(&self) -> Value {
552        unsafe {
553            let mut v = Value::from_type(self.1.type_());
554            gobject_sys::g_value_set_flags(v.to_glib_none_mut().0, (*self.0).value);
555            v
556        }
557    }
558
559    /// Convert flags values from a `Value`. This returns all flags that are set.
560    pub fn from_value(value: &Value) -> Vec<FlagsValue> {
561        unsafe {
562            let flags_class = FlagsClass::new(value.type_());
563            let mut res = Vec::new();
564            if let Some(flags_class) = flags_class {
565                let f = gobject_sys::g_value_get_flags(value.to_glib_none().0);
566                for v in flags_class.get_values() {
567                    if v.get_value() & f != 0 {
568                        res.push(v);
569                    }
570                }
571            }
572            res
573        }
574    }
575
576    /// Get `FlagsClass` to which the flags value belongs.
577    pub fn get_class(&self) -> &FlagsClass {
578        &self.1
579    }
580}
581
582impl PartialEq for FlagsValue {
583    fn eq(&self, other: &Self) -> bool {
584        self.get_value().eq(&other.get_value())
585    }
586}
587
588impl Eq for FlagsValue {}
589
590/// Builder for conveniently setting/unsetting flags and returning a `Value`.
591///
592/// Example for getting a flags property, unsetting some flags and setting the updated flags on the
593/// object again:
594///
595/// ```ignore
596/// let flags = obj.get_property("flags").unwrap();
597/// let flags_class = FlagsClass::new(flags.type_()).unwrap();
598/// let flags = flags_class.builder_with_value(flags).unwrap()
599///     .unset_by_nick("some-flag")
600///     .unset_by_nick("some-other-flag")
601///     .build()
602///     .unwrap();
603/// obj.set_property("flags", &flags).unwrap();
604/// ```
605///
606/// If setting/unsetting any value fails, `build()` returns `None`.
607pub struct FlagsBuilder<'a>(&'a FlagsClass, Option<Value>);
608impl<'a> FlagsBuilder<'a> {
609    fn new(flags_class: &FlagsClass) -> FlagsBuilder {
610        let value = Value::from_type(flags_class.type_());
611        FlagsBuilder(flags_class, Some(value))
612    }
613
614    fn new_with_value(flags_class: &FlagsClass, value: Value) -> FlagsBuilder {
615        FlagsBuilder(flags_class, Some(value))
616    }
617
618    /// Sets flags corresponding to integer value `f`.
619    pub fn set(mut self, f: u32) -> Self {
620        if let Some(value) = self.1.take() {
621            self.1 = self.0.set(value, f).ok();
622        }
623
624        self
625    }
626
627    /// Sets flags corresponding to string name `name`.
628    pub fn set_by_name(mut self, name: &str) -> Self {
629        if let Some(value) = self.1.take() {
630            self.1 = self.0.set_by_name(value, name).ok();
631        }
632
633        self
634    }
635
636    /// Sets flags corresponding to string nick `nick`.
637    pub fn set_by_nick(mut self, nick: &str) -> Self {
638        if let Some(value) = self.1.take() {
639            self.1 = self.0.set_by_nick(value, nick).ok();
640        }
641
642        self
643    }
644
645    /// Unsets flags corresponding to integer value `f`.
646    pub fn unset(mut self, f: u32) -> Self {
647        if let Some(value) = self.1.take() {
648            self.1 = self.0.unset(value, f).ok();
649        }
650
651        self
652    }
653
654    /// Unsets flags corresponding to string name `name`.
655    pub fn unset_by_name(mut self, name: &str) -> Self {
656        if let Some(value) = self.1.take() {
657            self.1 = self.0.unset_by_name(value, name).ok();
658        }
659
660        self
661    }
662
663    /// Unsets flags corresponding to string nick `nick`.
664    pub fn unset_by_nick(mut self, nick: &str) -> Self {
665        if let Some(value) = self.1.take() {
666            self.1 = self.0.unset_by_nick(value, nick).ok();
667        }
668
669        self
670    }
671
672    /// Converts to the final `Value`, unless any previous setting/unsetting of flags failed.
673    pub fn build(self) -> Option<Value> {
674        self.1
675    }
676}