Skip to main content

qttypes/
lib.rs

1/* Copyright (C) 2018 Olivier Goffart <ogoffart@woboq.com>
2
3Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
4associated documentation files (the "Software"), to deal in the Software without restriction,
5including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
6and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
7subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial
10portions of the Software.
11
12THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
13NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
15OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17*/
18//! This crate contains manually generated bindings to Qt basic value types.
19//! It is meant to be used by other crates, such as the `qmetaobject` crate which re-expose them.
20//!
21//! The Qt types are basically exposed using the [`mod@cpp`] crate. They have manually writen rust idiomatic
22//! API which expose the C++ API.
23//! These types are the direct equivalent of the Qt types and are exposed on the stack.
24//!
25//! In addition, the build script of this crate expose some metadata to downstream crate that also
26//! want to use Qt's C++ API.
27//! Build scripts of crates that depends directly from this crate will have the following
28//! environment variables set when the build script is run:
29//! - `DEP_QT_VERSION`: The Qt version as given by qmake.
30//! - `DEP_QT_INCLUDE_PATH`: The include directory to give to the `cpp_build` crate to locate the Qt headers.
31//! - `DEP_QT_LIBRARY_PATH`: The path containing the Qt libraries.
32//! - `DEP_QT_COMPILE_FLAGS`: A list of flags separated by `;`
33//! - `DEP_QT_FOUND`: Set to 1 when qt was found, or 0 if qt was not found and the `required` feature is not set.
34//! - `DEP_QT_ERROR_MESSAGE`: when `DEP_QT_FOUND` is 0, contains the error that caused the build to fail
35//!
36//! ## Finding Qt
37//!
38//! This is the algorithm used to find Qt.
39//!
40//! - You can set the environment variable `QT_INCLUDE_PATH` and `QT_LIBRARY_PATH` to be a single
41//!   directory where the Qt headers and Qt libraries are installed.
42//! - Otherwise you can specify a `QMAKE` environment variable with the absolute path of the
43//!   `qmake` executable which will be used to query these paths.
44//! - If none of these environment variable is set, the `qmake6` or `qmake` executable found in `$PATH`.
45//!
46//! ## Philosophy
47//!
48//! The goal of this crate is to expose a idiomatic Qt API for the core value type classes.
49//! The API is manually generated to expose required feature in the most rust-like API, while
50//! still keeping the similarities with the Qt API itself.
51//!
52//! It is not meant to expose all of the Qt API exhaustively, but only the part which is
53//! relevant for the usage in other crate.
54//! If you see a feature missing, feel free to write a issue or a pull request.
55//!
56//! Note that this crate concentrate on the value types, not the widgets or the
57//! the `QObject`.  For that, there is the `qmetaobject` crate.
58//!
59//! ## Usage with the `cpp` crate
60//!
61//! Here is an example that make use of the types exposed by this crate in combination
62//! with the [`mod@cpp`] crate to call native API:
63//!
64//! In `Cargo.toml`
65//! ```toml
66//! #...
67//! [dependencies]
68//! qttype = "0.1"
69//! cpp = "0.5"
70//! #...
71//! [build-dependencies]
72//! cpp_build = "0.5"
73//! ```
74//!
75//! Note: It is important to depend directly on `qttype`, it is not enough to rely on the
76//! dependency coming transitively from another dependencies, otherwise the `DEP_QT_*`
77//! environment variables won't be defined.
78//!
79//! Then in the `build.rs` file:
80//! ```rust,no_run
81//! fn main() {
82//!     let mut config = cpp_build::Config::new();
83//!     config.include(std::env::var("DEP_QT_INCLUDE_PATH").unwrap());
84//!     for f in std::env::var("DEP_QT_COMPILE_FLAGS").unwrap().split_terminator(";") {
85//!        config.flag(f);
86//!     }
87//!     config.build("src/main.rs");
88//! }
89//! ```
90//!
91//! With that, you can now use the types inside your .rs files:
92//!
93//! ```ignore
94//! let byte_array = qttypes::QByteArray::from("Hello World!");
95//! cpp::cpp!([byte_array as "QByteArray"] { qDebug() << byte_array; });
96//! ```
97//!
98//! You will find a small but working example in the
99//! [qmetaobject-rs repository](https://github.com/woboq/qmetaobject-rs/tree/master/examples/graph).
100//!
101//! ## Cargo Features
102//!
103//! - **`required`**: When this feature is enabled (the default), the build script will panic with an error
104//!   if Qt is not found. Otherwise, when not enabled, the build will continue, but any use of the classes will
105//!   panic at runtime.
106//! - **`chrono`**: enable the conversion between [`QDateTime`] related types and the types from the `chrono` crate.
107//!
108//! Link against these Qt modules using cargo features:
109//!
110//! | Cargo feature             | Qt module             |
111//! | ------------------------- | --------------------- |
112//! | **`qtmultimedia`**        | Qt Multimedia         |
113//! | **`qtmultimediawidgets`** | Qt Multimedia Widgets |
114//! | **`qtquick`**             | Qt Quick              |
115//! | **`qtquickcontrols2`**    | Qt Quick Controls     |
116//! | **`qtsql`**               | Qt SQL                |
117//! | **`qttest`**              | Qt Test               |
118//! | **`qtwebengine`**         | Qt WebEngine          |
119//!
120
121#![cfg_attr(no_qt, allow(unused))]
122
123use std::collections::HashMap;
124use std::convert::From;
125use std::fmt;
126use std::hash::Hash;
127use std::iter::FromIterator;
128use std::ops::{Index, IndexMut};
129
130#[cfg(feature = "chrono")]
131use chrono::prelude::*;
132
133#[cfg(no_qt)]
134pub(crate) mod no_qt {
135    pub fn panic<T>() -> T {
136        panic!("Qt was not found during build")
137    }
138}
139
140pub(crate) mod internal_prelude {
141    #[cfg(not(no_qt))]
142    pub(crate) use cpp::{cpp, cpp_class};
143    #[cfg(no_qt)]
144    macro_rules! cpp {
145        {{ $($t:tt)* }} => {};
146        {$(unsafe)? [$($a:tt)*] -> $ret:ty as $b:tt { $($t:tt)* } } => {
147            crate::no_qt::panic::<$ret>()
148        };
149        { $($t:tt)* } => {
150            crate::no_qt::panic::<()>()
151        };
152    }
153
154    #[cfg(no_qt)]
155    macro_rules! cpp_class {
156        ($(#[$($attrs:tt)*])* $vis:vis unsafe struct $name:ident as $type:expr) => {
157            #[derive(Default, Ord, Eq, PartialEq, PartialOrd, Clone, Copy)]
158            #[repr(C)]
159            $vis struct $name;
160        };
161    }
162    #[cfg(no_qt)]
163    pub(crate) use cpp;
164    #[cfg(no_qt)]
165    pub(crate) use cpp_class;
166}
167use internal_prelude::*;
168
169mod qtcore;
170pub use crate::qtcore::{
171    qreal, NormalizationForm, QByteArray, QListIterator, QSettings, QString, QStringList, QUrl,
172    QVariant, QVariantList, UnicodeVersion,
173};
174
175mod qtgui;
176pub use crate::qtgui::{QColor, QColorNameFormat, QColorSpec, QRgb, QRgba64};
177
178cpp! {{
179    #include <QtCore/QByteArray>
180    #include <QtCore/QDateTime>
181    #include <QtCore/QModelIndex>
182    #include <QtCore/QString>
183    #include <QtCore/QUrl>
184    #include <QtCore/QVariant>
185
186    #include <QtGui/QImage>
187    #include <QtGui/QPixmap>
188    #include <QtGui/QPainter>
189    #include <QtGui/QPen>
190    #include <QtGui/QBrush>
191}}
192
193cpp_class!(
194    /// Wrapper around [`QDate`][class] class.
195    ///
196    /// [class]: https://doc.qt.io/qt-5/qdate.html
197    #[derive(PartialEq, PartialOrd, Eq, Ord)]
198    pub unsafe struct QDate as "QDate"
199);
200impl QDate {
201    /// Wrapper around [`QDate(int y, int m, int d)`][ctor] constructor.
202    ///
203    /// [ctor]: https://doc.qt.io/qt-5/qdate.html#QDate-2
204    pub fn from_y_m_d(y: i32, m: i32, d: i32) -> Self {
205        cpp!(unsafe [y as "int", m as "int", d as "int"] -> QDate as "QDate" {
206            return QDate(y, m, d);
207        })
208    }
209
210    /// Wrapper around [`QDate::getDate(int *year, int *month, int *day)`][method] method.
211    ///
212    /// # Wrapper-specific
213    ///
214    /// Returns the year, month and day components as a tuple, instead of mutable references.
215    ///
216    /// [method]: https://doc.qt.io/qt-5/qdate.html#getDate
217    pub fn get_y_m_d(&self) -> (i32, i32, i32) {
218        let mut res = (0, 0, 0);
219        let (ref mut y, ref mut m, ref mut d) = res;
220
221        // In version prior to Qt 5.7, this method was marked non-const.
222        // A #[cfg(qt_5_7)] attribute does not solve that issue, because the cpp_build crate is not
223        // smart enough not to compile the non-qualifying closure.
224        cpp!(unsafe [self as "QDate*", y as "int*", m as "int*", d as "int*"] {
225            return self->getDate(y, m, d);
226        });
227
228        res
229    }
230
231    /// Wrapper around [`QDate::isValid()`][method] method.
232    ///
233    /// [method]: https://doc.qt.io/qt-5/qdate.html#isValid
234    pub fn is_valid(&self) -> bool {
235        cpp!(unsafe [self as "const QDate*"] -> bool as "bool" {
236            return self->isValid();
237        })
238    }
239}
240#[cfg(feature = "chrono")]
241impl From<NaiveDate> for QDate {
242    fn from(a: NaiveDate) -> QDate {
243        QDate::from_y_m_d(a.year() as i32, a.month() as i32, a.day() as i32)
244    }
245}
246#[cfg(feature = "chrono")]
247impl Into<NaiveDate> for QDate {
248    fn into(self) -> NaiveDate {
249        let (y, m, d) = self.get_y_m_d();
250        NaiveDate::from_ymd(y, m as u32, d as u32)
251    }
252}
253
254#[test]
255fn test_qdate() {
256    let date = QDate::from_y_m_d(2019, 10, 22);
257    assert_eq!((2019, 10, 22), date.get_y_m_d());
258}
259
260#[test]
261fn test_qdate_is_valid() {
262    let valid_qdate = QDate::from_y_m_d(2019, 10, 26);
263    assert!(valid_qdate.is_valid());
264
265    let invalid_qdate = QDate::from_y_m_d(-1, -1, -1);
266    assert!(!invalid_qdate.is_valid());
267}
268
269#[cfg(feature = "chrono")]
270#[test]
271fn test_qdate_chrono() {
272    let chrono_date = NaiveDate::from_ymd(2019, 10, 22);
273    let qdate: QDate = chrono_date.into();
274    let actual_chrono_date: NaiveDate = qdate.into();
275
276    // Ensure that conversion works for both the Into trait and get_y_m_d() function
277    assert_eq!((2019, 10, 22), qdate.get_y_m_d());
278    assert_eq!(chrono_date, actual_chrono_date);
279}
280
281cpp_class!(
282    /// Wrapper around [`QTime`][class] class.
283    ///
284    /// [class]: https://doc.qt.io/qt-5/qtime.html
285    #[derive(PartialEq, PartialOrd, Eq, Ord)]
286    pub unsafe struct QTime as "QTime"
287);
288impl QTime {
289    /// Wrapper around [`QTime(int h, int m, int s = 0, int ms = 0)`][ctor] constructor.
290    ///
291    /// # Wrapper-specific
292    ///
293    /// Default arguments converted to `Option`s.
294    ///
295    /// [ctor]: https://doc.qt.io/qt-5/qtime.html#QTime-2
296    pub fn from_h_m_s_ms(h: i32, m: i32, s: Option<i32>, ms: Option<i32>) -> Self {
297        let s = s.unwrap_or(0);
298        let ms = ms.unwrap_or(0);
299
300        cpp!(unsafe [h as "int", m as "int", s as "int", ms as "int"] -> QTime as "QTime" {
301            return QTime(h, m, s, ms);
302        })
303    }
304
305    /// Wrapper around [`QTime::hour()`][method] method.
306    ///
307    /// [method]: https://doc.qt.io/qt-5/qtime.html#hour
308    pub fn get_hour(&self) -> i32 {
309        cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
310            return self->hour();
311        })
312    }
313
314    /// Wrapper around [`QTime::minute()`][method] method.
315    ///
316    /// [method]: https://doc.qt.io/qt-5/qtime.html#minute
317    pub fn get_minute(&self) -> i32 {
318        cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
319            return self->minute();
320        })
321    }
322
323    /// Wrapper around [`QTime::second()`][method] method.
324    ///
325    /// [method]: https://doc.qt.io/qt-5/qtime.html#second
326    pub fn get_second(&self) -> i32 {
327        cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
328            return self->second();
329        })
330    }
331
332    /// Wrapper around [`QTime::msec()`][method] method.
333    ///
334    /// [method]: https://doc.qt.io/qt-5/qtime.html#msec
335    pub fn get_msec(&self) -> i32 {
336        cpp!(unsafe [self as "const QTime*"] -> i32 as "int" {
337            return self->msec();
338        })
339    }
340
341    /// Convenience function for obtaining the hour, minute, second and millisecond components.
342    pub fn get_h_m_s_ms(&self) -> (i32, i32, i32, i32) {
343        (self.get_hour(), self.get_minute(), self.get_second(), self.get_msec())
344    }
345
346    /// Wrapper around [`QTime::isValid()`][method] method.
347    ///
348    /// [method]: https://doc.qt.io/qt-5/qtime.html#isValid
349    pub fn is_valid(&self) -> bool {
350        cpp!(unsafe [self as "const QTime*"] -> bool as "bool" {
351            return self->isValid();
352        })
353    }
354}
355
356#[cfg(feature = "chrono")]
357impl From<NaiveTime> for QTime {
358    fn from(a: NaiveTime) -> QTime {
359        QTime::from_h_m_s_ms(
360            a.hour() as i32,
361            a.minute() as i32,
362            Some(a.second() as i32),
363            Some(a.nanosecond() as i32 / 1_000_000),
364        )
365    }
366}
367
368#[cfg(feature = "chrono")]
369impl Into<NaiveTime> for QTime {
370    fn into(self) -> NaiveTime {
371        let (h, m, s, ms) = self.get_h_m_s_ms();
372        NaiveTime::from_hms_milli(h as u32, m as u32, s as u32, ms as u32)
373    }
374}
375
376#[test]
377fn test_qtime() {
378    let qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300));
379    assert_eq!((10, 30, 40, 300), qtime.get_h_m_s_ms());
380}
381
382#[cfg(feature = "chrono")]
383#[test]
384fn test_qtime_chrono() {
385    let chrono_time = NaiveTime::from_hms(10, 30, 50);
386    let qtime: QTime = chrono_time.into();
387    let actual_chrono_time: NaiveTime = qtime.into();
388
389    // Ensure that conversion works for both the Into trait and get_h_m_s_ms() function
390    assert_eq!((10, 30, 50, 0), qtime.get_h_m_s_ms());
391    assert_eq!(chrono_time, actual_chrono_time);
392}
393
394#[test]
395fn test_qtime_is_valid() {
396    let valid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300));
397    assert!(valid_qtime.is_valid());
398
399    let invalid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(9999));
400    assert!(!invalid_qtime.is_valid());
401}
402
403cpp_class!(
404    /// Wrapper around [`QDateTime`][class] class.
405    ///
406    /// [class]: https://doc.qt.io/qt-5/qdatetime.html
407    #[derive(PartialEq, PartialOrd, Eq, Ord)]
408    pub unsafe struct QDateTime as "QDateTime"
409);
410impl QDateTime {
411    /// Wrapper around [`QDateTime(const QDateTime &other)`][ctor] constructor.
412    ///
413    /// [ctor]: https://doc.qt.io/qt-5/qdatetime.html#QDateTime-1
414    pub fn from_date(date: QDate) -> Self {
415        cpp!(unsafe [date as "QDate"] -> QDateTime as "QDateTime" {
416        #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
417                    return date.startOfDay();
418        #else
419                    return QDateTime(date);
420        #endif
421        })
422    }
423
424    /// Wrapper around [`QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec = Qt::LocalTime)`][ctor] constructor.
425    ///
426    /// # Wrapper-specific
427    ///
428    /// `spec` is left as it is, thus it is always `Qt::LocalTime`.
429    ///
430    /// [ctor]: https://doc.qt.io/qt-5/qdatetime.html#QDateTime-2
431    pub fn from_date_time_local_timezone(date: QDate, time: QTime) -> Self {
432        cpp!(unsafe [date as "QDate", time as "QTime"] -> QDateTime as "QDateTime" {
433            return QDateTime(date, time);
434        })
435    }
436
437    /// Wrapper around [`QDateTime::date()`][method] method.
438    ///
439    /// [method]: https://doc.qt.io/qt-5/qdatetime.html#date
440    pub fn get_date(&self) -> QDate {
441        cpp!(unsafe [self as "const QDateTime*"] -> QDate as "QDate" {
442            return self->date();
443        })
444    }
445
446    /// Wrapper around [`QDateTime::time()`][method] method.
447    ///
448    /// [method]: https://doc.qt.io/qt-5/qdatetime.html#time
449    pub fn get_time(&self) -> QTime {
450        cpp!(unsafe [self as "const QDateTime*"] -> QTime as "QTime" {
451            return self->time();
452        })
453    }
454
455    /// Convenience function for obtaining both date and time components.
456    pub fn get_date_time(&self) -> (QDate, QTime) {
457        (self.get_date(), self.get_time())
458    }
459
460    /// Wrapper around [`QDateTime::isValid()`][method] method.
461    ///
462    /// [method]: https://doc.qt.io/qt-5/qdatetime.html#isValid
463    pub fn is_valid(&self) -> bool {
464        cpp!(unsafe [self as "const QDateTime*"] -> bool as "bool" {
465            return self->isValid();
466        })
467    }
468}
469
470#[test]
471fn test_qdatetime_from_date() {
472    let qdate = QDate::from_y_m_d(2019, 10, 22);
473    let qdatetime = QDateTime::from_date(qdate);
474    let actual_qdate = qdatetime.get_date();
475
476    assert_eq!((2019, 10, 22), actual_qdate.get_y_m_d());
477}
478
479#[test]
480fn test_qdatetime_from_date_time_local_timezone() {
481    let qdate = QDate::from_y_m_d(2019, 10, 22);
482    let qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300));
483    let qdatetime = QDateTime::from_date_time_local_timezone(qdate, qtime);
484    let (actual_qdate, actual_qtime) = qdatetime.get_date_time();
485
486    assert_eq!((2019, 10, 22), actual_qdate.get_y_m_d());
487    assert_eq!((10, 30, 40, 300), actual_qtime.get_h_m_s_ms());
488
489    assert_eq!(10, actual_qtime.get_hour());
490    assert_eq!(30, actual_qtime.get_minute());
491    assert_eq!(40, actual_qtime.get_second());
492    assert_eq!(300, actual_qtime.get_msec());
493}
494
495#[test]
496fn test_qdatetime_is_valid() {
497    let valid_qdate = QDate::from_y_m_d(2019, 10, 26);
498    let invalid_qdate = QDate::from_y_m_d(-1, -1, -1);
499
500    let valid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(300));
501    let invalid_qtime = QTime::from_h_m_s_ms(10, 30, Some(40), Some(9999));
502
503    let valid_qdatetime_from_date = QDateTime::from_date(valid_qdate);
504    assert!(valid_qdatetime_from_date.is_valid());
505
506    let valid_qdatetime_from_valid_date_valid_time =
507        QDateTime::from_date_time_local_timezone(valid_qdate, valid_qtime);
508    assert!(valid_qdatetime_from_valid_date_valid_time.is_valid());
509
510    // Refer to the documentation for QDateTime's constructors using QDate, QTime.
511    // If the date is valid, but the time is not, the time will be set to midnight
512    let valid_qdatetime_from_valid_date_invalid_time =
513        QDateTime::from_date_time_local_timezone(valid_qdate, invalid_qtime);
514    assert!(valid_qdatetime_from_valid_date_invalid_time.is_valid());
515
516    let invalid_qdatetime_from_invalid_date_valid_time =
517        QDateTime::from_date_time_local_timezone(invalid_qdate, valid_qtime);
518    assert!(!invalid_qdatetime_from_invalid_date_valid_time.is_valid());
519
520    let invalid_qdatetime_from_invalid_date_invalid_time =
521        QDateTime::from_date_time_local_timezone(invalid_qdate, invalid_qtime);
522    assert!(!invalid_qdatetime_from_invalid_date_invalid_time.is_valid());
523}
524
525cpp_class!(
526    /// Wrapper around [`QVariantMap`][type] typedef.
527    ///
528    /// [type]: https://doc.qt.io/qt-5/qvariant.html#QVariantMap-typedef
529    #[derive(Default, PartialEq, Eq)]
530    pub unsafe struct QVariantMap as "QVariantMap"
531);
532
533impl QVariantMap {
534    /// Wrapper around [`insert(int, const QString &, const QVariant &)`][method] method.
535    ///
536    /// [method]: https://doc.qt.io/qt-5/qlist.html#insert
537    pub fn insert(&mut self, key: QString, element: QVariant) {
538        cpp!(unsafe [self as "QVariantMap*", key as "QString", element as "QVariant"] {
539            self->insert(key, std::move(element));
540        })
541    }
542
543    /// Wrapper around [`remove(const QString &)`][method] method.
544    ///
545    /// [method]: https://doc.qt.io/qt-5/qmap.html#remove
546    pub fn remove(&mut self, key: QString) -> usize {
547        cpp!(unsafe [self as "QVariantMap*", key as "QString"] -> usize as "size_t" {
548            return self->remove(key);
549        })
550    }
551
552    /// Wrapper around [`take(const QString &)`][method] method.
553    ///
554    /// [method]: https://doc.qt.io/qt-5/qmap.html#take
555    pub fn take(&mut self, key: QString) -> QVariant {
556        cpp!(unsafe [self as "QVariantMap*", key as "QString"] -> QVariant as "QVariant" {
557            return self->take(key);
558        })
559    }
560
561    /// Wrapper around [`size()`][method] method.
562    ///
563    /// [method]: https://doc.qt.io/qt-5/qmap.html#size
564    pub fn len(&self) -> usize {
565        cpp!(unsafe [self as "const QVariantMap*"] -> usize as "size_t" {
566            return self->size();
567        })
568    }
569
570    /// Wrapper around [`isEmpty()`][method] method.
571    ///
572    /// [method]: https://doc.qt.io/qt-5/qmap.html#isEmpty
573    pub fn is_empty(&self) -> bool {
574        cpp!(unsafe [self as "const QVariantMap*"] -> bool as "bool" {
575            return self->isEmpty();
576        })
577    }
578
579    /// Wrapper around [`contains(const QString &)`][method] method.
580    ///
581    /// [method]: https://doc.qt.io/qt-5/qmap.html#contains
582    pub fn contains(&self, key: QString) -> bool {
583        cpp!(unsafe [self as "const QVariantMap*", key as "QString"] -> bool as "bool" {
584            return self->contains(key);
585        })
586    }
587
588    /// Wrapper around [`clear()`][method] method.
589    ///
590    /// [method]: https://doc.qt.io/qt-5/qmap.html#clear
591    pub fn clear(&mut self) {
592        cpp!(unsafe [self as "QVariantMap*"] {
593            self->clear();
594        })
595    }
596
597    /// Wrapper around [`value(const QString &, const QVariant &)`][method] method.
598    ///
599    /// [method]: https://doc.qt.io/qt-5/qmap.html#value
600    pub fn value(&self, key: QString, default_value: QVariant) -> QVariant {
601        cpp!(unsafe [self as "const QVariantMap*", key as "QString", default_value as "QVariant"] -> QVariant as "QVariant" {
602            return self->value(key, default_value);
603        })
604    }
605
606    /// Wrapper around [`key(const QVariant &, const QString &)`][method] method.
607    ///
608    /// [method]: https://doc.qt.io/qt-5/qmap.html#key
609    pub fn key(&self, value: QVariant, default_key: QString) -> QString {
610        cpp!(unsafe [self as "const QVariantMap*", default_key as "QString", value as "QVariant"] -> QString as "QString" {
611            return self->key(value, default_key);
612        })
613    }
614}
615
616impl Index<QString> for QVariantMap {
617    type Output = QVariant;
618
619    /// Wrapper around [`at(int)`][method] method.
620    ///
621    /// [method]: https://doc.qt.io/qt-5/qlist.html#at
622    #[track_caller]
623    fn index(&self, key: QString) -> &Self::Output {
624        cpp!(unsafe [self as "const QVariantMap*", key as "QString"] -> Option<&QVariant> as "const QVariant*" {
625                auto x = self->constFind(key);
626                if (x == self->constEnd()) {
627                    return NULL;
628                } else {
629                    return &x.value();
630                }
631            }).expect("key not in the QVariant")
632    }
633}
634impl IndexMut<QString> for QVariantMap {
635    /// Wrapper around [`operator[](int)`][method] operator method.
636    ///
637    /// [method]: https://doc.qt.io/qt-5/qlist.html#operator-5b-5d
638    fn index_mut(&mut self, key: QString) -> &mut Self::Output {
639        unsafe {
640            &mut *cpp!([self as "QVariantMap*", key as "QString"] -> *mut QVariant as "QVariant*" {
641                return &(*self)[key];
642            })
643        }
644    }
645}
646
647impl fmt::Debug for QVariantMap {
648    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
649        f.debug_map().entries(self.into_iter()).finish()
650    }
651}
652
653cpp_class!(unsafe struct QVariantMapIteratorInternal as "QVariantMap::iterator");
654
655/// Internal class used to iterate over a [`QVariantMap`]
656pub struct QVariantMapIterator<'a> {
657    map: &'a QVariantMap,
658    iterator: QVariantMapIteratorInternal,
659}
660
661impl<'a> QVariantMapIterator<'a> {
662    fn key(&self) -> Option<&'a QString> {
663        let iterator = &self.iterator;
664        cpp!(unsafe [iterator as "const QVariantMap::iterator*"] -> Option<&QString> as "const QString*" {
665            return &iterator->key();
666        })
667    }
668
669    fn value(&self) -> Option<&'a QVariant> {
670        let iterator = &self.iterator;
671        cpp!(unsafe [iterator as "const QVariantMap::iterator*"] -> Option<&QVariant> as "QVariant*" {
672            return &iterator->value();
673        })
674    }
675
676    fn check_end(&self) -> bool {
677        let map = self.map;
678        let iterator = &self.iterator;
679        cpp!(unsafe [iterator as "const QVariantMap::iterator*", map as "const QVariantMap*"] -> bool as "bool" {
680            return (*iterator == map->end());
681        })
682    }
683
684    fn increment(&mut self) {
685        let iterator = &self.iterator;
686        cpp!(unsafe [iterator as "QVariantMap::iterator*"] {
687            ++(*iterator);
688        })
689    }
690}
691
692impl<'a> Iterator for QVariantMapIterator<'a> {
693    type Item = (&'a QString, &'a QVariant);
694
695    fn next(&mut self) -> Option<Self::Item> {
696        if self.check_end() {
697            return None;
698        }
699
700        let key = self.key();
701        let value = self.value();
702
703        self.increment();
704
705        match (key, value) {
706            (Some(k), Some(v)) => Some((k, v)),
707            _ => None,
708        }
709    }
710}
711
712impl<'a> IntoIterator for &'a QVariantMap {
713    type Item = (&'a QString, &'a QVariant);
714    type IntoIter = QVariantMapIterator<'a>;
715
716    fn into_iter(self) -> Self::IntoIter {
717        let iter = cpp!(unsafe [self as "QVariantMap*"] -> QVariantMapIteratorInternal as "QVariantMap::iterator" {
718            return self->begin();
719        });
720        Self::IntoIter { map: self, iterator: iter }
721    }
722}
723
724impl<K, V> FromIterator<(K, V)> for QVariantMap
725where
726    K: Into<QString>,
727    V: Into<QVariant>,
728{
729    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
730        let mut m = QVariantMap::default();
731        for i in iter {
732            let (k, v) = i;
733            m.insert(k.into(), v.into());
734        }
735        m
736    }
737}
738
739impl<K, V> From<HashMap<K, V>> for QVariantMap
740where
741    K: Into<QString>,
742    V: Into<QVariant>,
743{
744    fn from(m: HashMap<K, V>) -> Self {
745        m.into_iter().collect()
746    }
747}
748
749impl<K, V, const N: usize> From<[(K, V); N]> for QVariantMap
750where
751    K: Into<QString>,
752    V: Into<QVariant>,
753{
754    fn from(m: [(K, V); N]) -> Self {
755        let mut temp = QVariantMap::default();
756        for (key, val) in m {
757            temp.insert(key.into(), val.into());
758        }
759        temp
760    }
761}
762
763impl<K, V> From<QVariantMap> for HashMap<K, V>
764where
765    K: Hash + Eq,
766    V: Eq,
767    QString: Into<K>,
768    QVariant: Into<V>,
769{
770    fn from(m: QVariantMap) -> Self {
771        m.into_iter().map(|(k, v)| (k.clone().into(), v.clone().into())).collect()
772    }
773}
774
775#[cfg(test)]
776mod qvariantmap_tests {
777    use super::*;
778
779    #[test]
780    fn test_qvariantmap() {
781        let mut map = QVariantMap::default();
782
783        let key1 = QString::from("a");
784        let val1 = QString::from("abc");
785
786        assert!(map.is_empty());
787        map.insert(key1.clone(), val1.clone().into());
788        assert_eq!(map.len(), 1);
789        assert_eq!(map[key1.clone()].to_qbytearray().to_string(), val1.to_string());
790
791        assert_eq!(map.take(key1.clone()).to_qbytearray().to_string(), val1.to_string());
792        assert!(map.is_empty());
793
794        map[key1.clone()] = val1.clone().into();
795
796        let default_value = QVariant::from(10);
797
798        assert_eq!(map[key1.clone()].to_qbytearray().to_string(), val1.to_string());
799        assert_eq!(map.value(key1.clone(), default_value.clone()), val1.clone().into());
800        assert_eq!(map.value(val1.clone(), default_value.clone()), default_value.clone());
801
802        assert_eq!(map.key(val1.clone().into(), val1.clone()), key1.clone());
803        assert_eq!(map.key(key1.clone().into(), val1.clone()), val1.clone());
804    }
805
806    #[test]
807    #[should_panic(expected = "key not in the QVariant")]
808    fn test_index_panic() {
809        let map = QVariantMap::default();
810
811        map[QString::from("t")].to_qbytearray().to_string();
812    }
813
814    #[test]
815    fn test_iter() {
816        let hashmap =
817            HashMap::from([("Mercury", 0.4), ("Venus", 0.7), ("Earth", 1.0), ("Mars", 1.5)]);
818        let map: QVariantMap = hashmap.clone().into();
819
820        assert_eq!(map.len(), hashmap.len());
821
822        for (k, v) in map.into_iter() {
823            assert_eq!(hashmap[k.to_string().as_str()].to_string(), v.to_qbytearray().to_string());
824        }
825    }
826
827    #[test]
828    fn test_from() {
829        let hashmap1 = HashMap::from([
830            ("A".to_string(), QVariant::from(QString::from("abc"))),
831            ("B".to_string(), QVariant::from(QString::from("def"))),
832        ]);
833        let qvariantmap1: QVariantMap = hashmap1.clone().into();
834        let hashmap2 = qvariantmap1.clone().into();
835        assert_eq!(hashmap1, hashmap2);
836
837        let qvariantmap2 = QVariantMap::from([
838            ("A".to_string(), QVariant::from(QString::from("abc"))),
839            ("B".to_string(), QVariant::from(QString::from("def"))),
840        ]);
841        assert_eq!(qvariantmap1, qvariantmap2);
842    }
843}
844
845cpp_class!(
846    /// Wrapper around [`QModelIndex`][class] class.
847    ///
848    /// [class]: https://doc.qt.io/qt-5/qmodelindex.html
849    #[derive(PartialEq, Eq)]
850    pub unsafe struct QModelIndex as "QModelIndex"
851);
852impl QModelIndex {
853    /// Wrapper around [`internalId()`][method] method.
854    ///
855    /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#internalId
856    pub fn id(&self) -> usize {
857        cpp!(unsafe [self as "const QModelIndex*"] -> usize as "uintptr_t" { return self->internalId(); })
858    }
859
860    /// Wrapper around [`column()`][method] method.
861    ///
862    /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#column
863    pub fn column(&self) -> i32 {
864        cpp!(unsafe [self as "const QModelIndex*"] -> i32 as "int" { return self->column(); })
865    }
866
867    /// Wrapper around [`row()`][method] method.
868    ///
869    /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#row
870    pub fn row(&self) -> i32 {
871        cpp!(unsafe [self as "const QModelIndex*"] -> i32 as "int" { return self->row(); })
872    }
873
874    /// Wrapper around [`isValid()`][method] method.
875    ///
876    /// [method]: https://doc.qt.io/qt-5/qmodelindex.html#isValid
877    pub fn is_valid(&self) -> bool {
878        cpp!(unsafe [self as "const QModelIndex*"] -> bool as "bool" { return self->isValid(); })
879    }
880}
881
882/// Bindings for [`QRectF`][class] class.
883///
884/// [class]: https://doc.qt.io/qt-5/qrectf.html
885#[repr(C)]
886#[derive(Default, Clone, Copy, PartialEq, Debug)]
887pub struct QRectF {
888    pub x: qreal,
889    pub y: qreal,
890    pub width: qreal,
891    pub height: qreal,
892}
893impl QRectF {
894    /// Wrapper around [`contains(const QPointF &)`][method] method.
895    ///
896    /// [method]: https://doc.qt.io/qt-5/qrectf.html#contains
897    pub fn contains(&self, pos: QPointF) -> bool {
898        cpp!(unsafe [self as "const QRectF*", pos as "QPointF"] -> bool as "bool" {
899            return self->contains(pos);
900        })
901    }
902
903    /// Same as the [`topLeft`][method] method.
904    ///
905    /// [method]: https://doc.qt.io/qt-5/qrectf.html#topLeft
906    pub fn top_left(&self) -> QPointF {
907        QPointF { x: self.x, y: self.y }
908    }
909
910    /// Same as the [`isValid`][method] method.
911    ///
912    /// [method]: https://doc.qt.io/qt-5/qrectf.html#isValid
913    pub fn is_valid(&self) -> bool {
914        self.width > 0. && self.height > 0.
915    }
916}
917
918/// Bindings for [`QPointF`][class] class.
919///
920/// [class]: https://doc.qt.io/qt-5/qpointf.html
921#[repr(C)]
922#[derive(Default, Clone, Copy, PartialEq, Debug)]
923pub struct QPointF {
924    pub x: qreal,
925    pub y: qreal,
926}
927impl std::ops::Add for QPointF {
928    type Output = QPointF;
929    /// Wrapper around [`operator+(const QPointF &, const QPointF &)`][func] function.
930    ///
931    /// [func]: https://doc.qt.io/qt-5/qpointf.html#operator-2b
932    fn add(self, other: QPointF) -> QPointF {
933        QPointF { x: self.x + other.x, y: self.y + other.y }
934    }
935}
936impl std::ops::AddAssign for QPointF {
937    /// Wrapper around [`operator+=(const QPointF &`][method] method.
938    ///
939    /// [method]: https://doc.qt.io/qt-5/qpointf.html#operator-2b-eq
940    fn add_assign(&mut self, other: QPointF) {
941        *self = QPointF { x: self.x + other.x, y: self.y + other.y };
942    }
943}
944
945/// Bindings for [`QSizeF`][class] class.
946///
947/// [class]: https://doc.qt.io/qt-5/qsizef.html
948#[repr(C)]
949#[derive(Default, Clone, Copy, PartialEq, Debug)]
950pub struct QSizeF {
951    pub width: qreal,
952    pub height: qreal,
953}
954
955#[test]
956fn test_qpointf_qrectf() {
957    let rect = QRectF { x: 200., y: 150., width: 60., height: 75. };
958    let pt = QPointF { x: 12., y: 5.5 };
959    assert!(!rect.contains(pt));
960    assert!(rect.contains(pt + rect.top_left()));
961}
962
963/// Bindings for [`QSize`][class] class.
964///
965/// [class]: https://doc.qt.io/qt-5/qsize.html
966#[repr(C)]
967#[derive(Default, Clone, Copy, PartialEq, Debug)]
968pub struct QSize {
969    pub width: u32,
970    pub height: u32,
971}
972
973/// Bindings for [`QPoint`][class] class.
974///
975/// [class]: https://doc.qt.io/qt-5/qpoint.html
976#[repr(C)]
977#[derive(Default, Clone, Copy, PartialEq, Debug)]
978pub struct QPoint {
979    pub x: i32,
980    pub y: i32,
981}
982
983/// Bindings for [`QMargins`][class] class.
984///
985/// [class]: https://doc.qt.io/qt-5/qmargins.html
986#[repr(C)]
987#[derive(Default, Clone, Copy, PartialEq, Debug)]
988pub struct QMargins {
989    pub left: i32,
990    pub top: i32,
991    pub right: i32,
992    pub bottom: i32,
993}
994
995/// Bindings for [`QImage::Format`][class] enum class.
996///
997/// [class]: https://doc.qt.io/qt-5/qimage.html#Format-enum
998#[repr(C)]
999#[derive(Clone, Copy, PartialEq, Debug)]
1000#[allow(non_camel_case_types)]
1001pub enum ImageFormat {
1002    Invalid = 0,
1003    Mono = 1,
1004    MonoLSB = 2,
1005    Indexed8 = 3,
1006    RGB32 = 4,
1007    ARGB32 = 5,
1008    ARGB32_Premultiplied = 6,
1009    RGB16 = 7,
1010    ARGB8565_Premultiplied = 8,
1011    RGB666 = 9,
1012    ARGB6666_Premultiplied = 10,
1013    RGB555 = 11,
1014    ARGB8555_Premultiplied = 12,
1015    RGB888 = 13,
1016    RGB444 = 14,
1017    ARGB4444_Premultiplied = 15,
1018    RGBX8888 = 16,
1019    RGBA8888 = 17,
1020    RGBA8888_Premultiplied = 18,
1021    BGR30 = 19,
1022    A2BGR30_Premultiplied = 20,
1023    RGB30 = 21,
1024    A2RGB30_Premultiplied = 22,
1025    Alpha8 = 23,
1026    Grayscale8 = 24,
1027    Grayscale16 = 28,
1028    RGBX64 = 25,
1029    RGBA64 = 26,
1030    RGBA64_Premultiplied = 27,
1031    BGR888 = 29,
1032}
1033cpp_class!(
1034    /// Wrapper around [`QImage`][class] class.
1035    ///
1036    /// [class]: https://doc.qt.io/qt-5/qimage.html
1037    #[derive(Default, Clone, PartialEq)]
1038    pub unsafe struct QImage as "QImage"
1039);
1040impl QImage {
1041    /// Wrapper around [`QImage(const QString &fileName, const char *format = nullptr)`][ctor] constructor.
1042    ///
1043    /// [ctor]: https://doc.qt.io/qt-5/qimage.html#QImage-8
1044    pub fn load_from_file(filename: QString) -> Self {
1045        cpp!(unsafe [filename as "QString"] -> QImage as "QImage" {
1046            return QImage(filename);
1047        })
1048    }
1049
1050    /// Wrapper around [`QImage(const QSize &, QImage::Format)`][ctor] constructor.
1051    ///
1052    /// [ctor]: https://doc.qt.io/qt-5/qimage.html#QImage-1
1053    pub fn new(size: QSize, format: ImageFormat) -> Self {
1054        cpp!(unsafe [size as "QSize", format as "QImage::Format" ] -> QImage as "QImage" {
1055            return QImage(size, format);
1056        })
1057    }
1058
1059    /// Wrapper around [`size()`][method] method.
1060    ///
1061    /// [method]: https://doc.qt.io/qt-5/qimage.html#size
1062    pub fn size(&self) -> QSize {
1063        cpp!(unsafe [self as "const QImage*"] -> QSize as "QSize" { return self->size(); })
1064    }
1065
1066    /// Wrapper around [`format()`][method] method.
1067    ///
1068    /// [method]: https://doc.qt.io/qt-5/qimage.html#format
1069    pub fn format(&self) -> ImageFormat {
1070        cpp!(unsafe [self as "const QImage*"] -> ImageFormat as "QImage::Format" { return self->format(); })
1071    }
1072
1073    /// Wrapper around [`fill(const QColor &)`][method] method.
1074    ///
1075    /// [method]: https://doc.qt.io/qt-5/qimage.html#fill-1
1076    pub fn fill(&mut self, color: QColor) {
1077        cpp!(unsafe [self as "QImage*", color as "QColor"] { self->fill(color); })
1078    }
1079
1080    /// Wrapper around [`setPixelColor(const QPoint &, const QColor &)`][method] method.
1081    ///
1082    /// [method]: https://doc.qt.io/qt-5/qimage.html#setPixelColor
1083    pub fn set_pixel_color(&mut self, x: u32, y: u32, color: QColor) {
1084        cpp!(unsafe [self as "QImage*", x as "int", y as "int", color as "QColor"] {
1085            self->setPixelColor(x, y, color);
1086        })
1087    }
1088
1089    /// Wrapper around [`pixelColor(const QPoint &)`][method] method.
1090    ///
1091    /// [method]: https://doc.qt.io/qt-5/qimage.html#pixelColor
1092    pub fn get_pixel_color(&self, x: u32, y: u32) -> QColor {
1093        cpp!(unsafe [self as "const QImage*", x as "int", y as "int"] -> QColor as "QColor" {
1094            return self->pixelColor(x, y);
1095        })
1096    }
1097}
1098
1099cpp_class!(
1100    /// Wrapper around [`QPixmap`][class] class.
1101    ///
1102    /// [class]: https://doc.qt.io/qt-5/qpixmap.html
1103    pub unsafe struct QPixmap as "QPixmap"
1104);
1105
1106impl QPixmap {
1107    /// Wrapper around [`size()`][method] method.
1108    ///
1109    /// [method]: https://doc.qt.io/qt-5/qpixmap.html#size
1110    pub fn size(&self) -> QSize {
1111        cpp!(unsafe [self as "const QPixmap*"] -> QSize as "QSize" { return self->size(); })
1112    }
1113}
1114
1115impl From<QPixmap> for QImage {
1116    fn from(pixmap: QPixmap) -> Self {
1117        cpp!(unsafe [pixmap as "QPixmap"] -> QImage as "QImage" { return pixmap.toImage(); })
1118    }
1119}
1120
1121impl From<QImage> for QPixmap {
1122    fn from(image: QImage) -> Self {
1123        cpp!(unsafe [image as "QImage"] -> QPixmap as "QPixmap" { return QPixmap::fromImage(image); })
1124    }
1125}
1126
1127/// Bindings for [`Qt::PenStyle`][enum] enum.
1128///
1129/// [enum]: https://doc.qt.io/qt-5/qt.html#PenStyle-enum
1130#[repr(C)]
1131#[derive(Clone, Copy, PartialEq, Debug)]
1132#[allow(non_camel_case_types)]
1133pub enum PenStyle {
1134    NoPen = 0,
1135    SolidLine = 1,
1136    DashLine = 2,
1137    DotLine = 3,
1138    DashDotLine = 4,
1139    DashDotDotLine = 5,
1140    CustomDashLine = 6,
1141}
1142cpp_class!(
1143    /// Wrapper around [`QPen`][class] class.
1144    ///
1145    /// [class]: https://doc.qt.io/qt-5/qpen.html
1146    #[derive(Default)]
1147    pub unsafe struct QPen as "QPen"
1148);
1149
1150impl QPen {
1151    pub fn from_color(color: QColor) -> Self {
1152        cpp!(unsafe [color as "QColor"] -> QPen as "QPen" { return QPen(color); })
1153    }
1154    pub fn from_style(style: PenStyle) -> Self {
1155        cpp!(unsafe [style as "Qt::PenStyle"] -> QPen as "QPen" { return QPen(style); })
1156    }
1157    pub fn set_color(&mut self, color: QColor) {
1158        cpp!(unsafe [self as "QPen*", color as "QColor"] { return self->setColor(color); });
1159    }
1160    pub fn set_style(&mut self, style: PenStyle) {
1161        cpp!(unsafe [self as "QPen*", style as "Qt::PenStyle"] { return self->setStyle(style); });
1162    }
1163    pub fn set_width(&mut self, width: i32) {
1164        cpp!(unsafe [self as "QPen*", width as "int"] { return self->setWidth(width); });
1165    }
1166    pub fn set_width_f(&mut self, width: qreal) {
1167        cpp!(unsafe [self as "QPen*", width as "qreal"] { return self->setWidthF(width); });
1168    }
1169
1170    //    QBrush	brush() const
1171    //    Qt::PenCapStyle	capStyle() const
1172    //    QColor	color() const
1173    //    qreal	dashOffset() const
1174    //    QVector<qreal>	dashPattern() const
1175    //    bool	isCosmetic() const
1176    //    bool	isSolid() const
1177    //    Qt::PenJoinStyle	joinStyle() const
1178    //    qreal	miterLimit() const
1179    //    void	setBrush(const QBrush &brush)
1180    //    void	setCapStyle(Qt::PenCapStyle style)
1181    //    void	setCosmetic(bool cosmetic)
1182    //    void	setDashOffset(qreal offset)
1183    //    void	setDashPattern(const QVector<qreal> &pattern)
1184    //    void	setJoinStyle(Qt::PenJoinStyle style)
1185    //    void	setMiterLimit(qreal limit)
1186    //    Qt::PenStyle	style() const
1187    //    void	swap(QPen &other)
1188    //    int	width() const
1189    //    qreal	widthF() const
1190}
1191
1192/// Bindings for [`QStandardPaths::StandardLocation`][enum] enum.
1193///
1194/// [enum]: https://doc.qt.io/qt-5/qstandardpaths.html#StandardLocation-enum
1195#[repr(C)]
1196#[derive(Clone, Copy, PartialEq, Debug)]
1197#[allow(non_camel_case_types)]
1198pub enum QStandardPathLocation {
1199    DesktopLocation = 0,
1200    DocumentsLocation = 1,
1201    FontsLocation = 2,
1202    ApplicationsLocation = 3,
1203    MusicLocation = 4,
1204    MoviesLocation = 5,
1205    PicturesLocation = 6,
1206    TempLocation = 7,
1207    HomeLocation = 8,
1208    AppLocalDataLocation = 9,
1209    CacheLocation = 10,
1210    GenericDataLocation = 11,
1211    RuntimeLocation = 12,
1212    ConfigLocation = 13,
1213    DownloadLocation = 14,
1214    GenericCacheLocation = 15,
1215    GenericConfigLocation = 16,
1216    AppDataLocation = 17,
1217    AppConfigLocation = 18,
1218}
1219
1220/// Bindings for [`Qt::BrushStyle`][enum] enum.
1221///
1222/// [enum]: https://doc.qt.io/qt-5/qt.html#BrushStyle-enum
1223#[repr(C)]
1224#[derive(Clone, Copy, PartialEq, Debug)]
1225#[allow(non_camel_case_types)]
1226pub enum BrushStyle {
1227    NoBrush = 0,
1228    SolidPattern = 1,
1229    Dense1Pattern = 2,
1230    Dense2Pattern = 3,
1231    Dense3Pattern = 4,
1232    Dense4Pattern = 5,
1233    Dense5Pattern = 6,
1234    Dense6Pattern = 7,
1235    Dense7Pattern = 8,
1236    HorPattern = 9,
1237    VerPattern = 10,
1238    CrossPattern = 11,
1239    BDiagPattern = 12,
1240    FDiagPattern = 13,
1241    DiagCrossPattern = 14,
1242    LinearGradientPattern = 15,
1243    ConicalGradientPattern = 17,
1244    RadialGradientPattern = 16,
1245    TexturePattern = 24,
1246}
1247cpp_class!(
1248    /// Wrapper around [`QBrush`][class] class.
1249    ///
1250    /// [class]: https://doc.qt.io/qt-5/qbrush.html
1251    #[derive(Default)]
1252    pub unsafe struct QBrush as "QBrush "
1253);
1254impl QBrush {
1255    pub fn from_color(color: QColor) -> Self {
1256        cpp!(unsafe [color as "QColor"] -> QBrush as "QBrush" { return QBrush(color); })
1257    }
1258    pub fn from_style(style: BrushStyle) -> Self {
1259        cpp!(unsafe [style as "Qt::BrushStyle"] -> QBrush as "QBrush" { return QBrush(style); })
1260    }
1261    pub fn set_color(&mut self, color: QColor) {
1262        cpp!(unsafe [self as "QBrush*", color as "QColor"] { return self->setColor(color); });
1263    }
1264    pub fn set_style(&mut self, style: BrushStyle) {
1265        cpp!(unsafe [self as "QBrush*", style as "Qt::BrushStyle"] { return self->setStyle(style); });
1266    }
1267}
1268
1269/// Bindings for [`QLineF`][class] class.
1270///
1271/// [class]: https://doc.qt.io/qt-5/qlinef.html
1272#[repr(C)]
1273#[derive(Default, Clone, Copy, PartialEq, Debug)]
1274pub struct QLineF {
1275    pub pt1: QPointF,
1276    pub pt2: QPointF,
1277}
1278
1279cpp_class!(
1280    /// Wrapper around [`QPainter`][class] class.
1281    ///
1282    /// [class]: https://doc.qt.io/qt-5/qpainter.html
1283    pub unsafe struct QPainter as "QPainter "
1284);
1285impl QPainter {
1286    pub fn draw_arc(&mut self, rectangle: QRectF, start_angle: i32, span_angle: i32) {
1287        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", start_angle as "int", span_angle as "int"] {
1288            self->drawArc(rectangle, start_angle, span_angle);
1289        });
1290    }
1291    pub fn draw_chord(&mut self, rectangle: QRectF, start_angle: i32, span_angle: i32) {
1292        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", start_angle as "int", span_angle as "int"] {
1293            self->drawChord(rectangle, start_angle, span_angle);
1294        });
1295    }
1296
1297    pub fn draw_convex_polygon(&mut self, points: &[QPointF]) {
1298        let points_ptr = points.as_ptr();
1299        let points_count = points.len() as u64;
1300        cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1301            self->drawConvexPolygon(points_ptr, points_count);
1302        });
1303    }
1304
1305    pub fn draw_ellipse(&mut self, rectangle: QRectF) {
1306        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF"] {
1307            self->drawEllipse(rectangle);
1308        });
1309    }
1310    pub fn draw_ellipse_with_center(&mut self, center: QPointF, rx: qreal, ry: qreal) {
1311        cpp!(unsafe [self as "QPainter *", center as "QPointF", rx as "qreal", ry as "qreal"] {
1312            self->drawEllipse(center, rx, ry);
1313        });
1314    }
1315
1316    pub fn draw_image_fit_rect(&mut self, rectangle: QRectF, image: QImage) {
1317        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", image as "QImage"] {
1318            self->drawImage(rectangle, image);
1319        });
1320    }
1321    pub fn draw_image_at_point(&mut self, point: QPointF, image: QImage) {
1322        cpp!(unsafe [self as "QPainter *", point as "QPointF", image as "QImage"] {
1323            self->drawImage(point, image);
1324        });
1325    }
1326    pub fn draw_image_fit_rect_with_source(
1327        &mut self,
1328        rectangle: QRectF,
1329        image: QImage,
1330        source_rect: QRectF,
1331    ) {
1332        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", image as "QImage", source_rect as "QRectF"] {
1333            self->drawImage(rectangle, image, source_rect);
1334        });
1335    }
1336    pub fn draw_image_at_point_with_source(
1337        &mut self,
1338        point: QPointF,
1339        image: QImage,
1340        source_rect: QRectF,
1341    ) {
1342        cpp!(unsafe [self as "QPainter *", point as "QPointF", image as "QImage", source_rect as "QRectF"] {
1343            self->drawImage(point, image, source_rect);
1344        });
1345    }
1346
1347    pub fn draw_line(&mut self, line: QLineF) {
1348        cpp!(unsafe [self as "QPainter *", line as "QLineF"] {
1349            self->drawLine(line);
1350        });
1351    }
1352    pub fn draw_lines(&mut self, lines: &[QLineF]) {
1353        let lines_ptr = lines.as_ptr();
1354        let lines_count = lines.len() as u64;
1355        cpp!(unsafe [self as "QPainter *", lines_ptr as "QLineF*", lines_count as "uint64_t"] {
1356            self->drawLines(lines_ptr, lines_count);
1357        });
1358    }
1359    pub fn draw_lines_from_points(&mut self, point_pairs: &[QPointF]) {
1360        let point_pairs_ptr = point_pairs.as_ptr();
1361        let point_pairs_count = point_pairs.len() as u64;
1362        cpp!(unsafe [self as "QPainter *", point_pairs_ptr as "QLineF*", point_pairs_count as "uint64_t"] {
1363            self->drawLines(point_pairs_ptr, point_pairs_count);
1364        });
1365    }
1366
1367    pub fn draw_pie(&mut self, rectangle: QRectF, start_angle: i32, span_angle: i32) {
1368        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", start_angle as "int", span_angle as "int"] {
1369            self->drawPie(rectangle, start_angle, span_angle);
1370        });
1371    }
1372
1373    pub fn draw_point(&mut self, point: QPointF) {
1374        cpp!(unsafe [self as "QPainter *", point as "QPointF"] {
1375            self->drawPoint(point);
1376        });
1377    }
1378    pub fn draw_points(&mut self, points: &[QPointF]) {
1379        let points_ptr = points.as_ptr();
1380        let points_count = points.len() as u64;
1381        cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1382            self->drawPoints(points_ptr, points_count);
1383        });
1384    }
1385
1386    pub fn draw_polygon(&mut self, points: &[QPointF]) {
1387        let points_ptr = points.as_ptr();
1388        let points_count = points.len() as u64;
1389        cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1390            self->drawPolygon(points_ptr, points_count);
1391        });
1392    }
1393    pub fn draw_polyline(&mut self, points: &[QPointF]) {
1394        let points_ptr = points.as_ptr();
1395        let points_count = points.len() as u64;
1396        cpp!(unsafe [self as "QPainter *", points_ptr as "QPointF*", points_count as "uint64_t"] {
1397            self->drawPolyline(points_ptr, points_count);
1398        });
1399    }
1400
1401    pub fn draw_rect(&mut self, rectangle: QRectF) {
1402        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF"] {
1403            self->drawRect(rectangle);
1404        });
1405    }
1406    pub fn draw_rects(&mut self, rects: &[QRectF]) {
1407        let rects_ptr = rects.as_ptr();
1408        let rects_count = rects.len() as u64;
1409        cpp!(unsafe [self as "QPainter *", rects_ptr as "QRectF*", rects_count as "uint64_t"] {
1410            self->drawRects(rects_ptr, rects_count);
1411        });
1412    }
1413    pub fn draw_rounded_rect(&mut self, rect: QRectF, x_radius: qreal, y_radius: qreal) {
1414        cpp!(unsafe [self as "QPainter *", rect as "QRectF", x_radius as "qreal", y_radius as "qreal"] {
1415            self->drawRoundedRect(rect, x_radius, y_radius);
1416        });
1417    }
1418
1419    pub fn draw_text(&mut self, position: QPointF, text: QString) {
1420        cpp!(unsafe [self as "QPainter *", position as "QPointF", text as "QString"] {
1421            self->drawText(position, text);
1422        });
1423    }
1424    pub fn draw_text_in_rect(&mut self, rectangle: QRectF, flags: u32, text: QString) -> QRectF {
1425        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", flags as "uint32_t", text as "QString"] -> QRectF as "QRectF" {
1426            QRectF boundingRect;
1427            self->drawText(rectangle, flags, text, &boundingRect);
1428            return boundingRect;
1429        })
1430    }
1431
1432    pub fn erase_rect(&mut self, rectangle: QRectF) {
1433        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF"] {
1434            self->eraseRect(rectangle);
1435        });
1436    }
1437
1438    pub fn fill_rect(&mut self, rectangle: QRectF, brush: QBrush) {
1439        cpp!(unsafe [self as "QPainter *", rectangle as "QRectF", brush as "QBrush"] {
1440            self->fillRect(rectangle, brush);
1441        });
1442    }
1443
1444    pub fn reset_transform(&mut self) {
1445        cpp!(unsafe [self as "QPainter *"] {
1446            self->resetTransform();
1447        });
1448    }
1449
1450    pub fn restore(&mut self) {
1451        cpp!(unsafe [self as "QPainter *"] {
1452            self->restore();
1453        });
1454    }
1455
1456    pub fn rotate(&mut self, angle: qreal) {
1457        cpp!(unsafe [self as "QPainter *", angle as "qreal"] {
1458            self->rotate(angle);
1459        });
1460    }
1461
1462    pub fn save(&mut self) {
1463        cpp!(unsafe [self as "QPainter *"] {
1464            self->save();
1465        });
1466    }
1467
1468    pub fn scale(&mut self, sx: qreal, sy: qreal) {
1469        cpp!(unsafe [self as "QPainter *", sx as "qreal", sy as "qreal"] {
1470            self->scale(sx, sy);
1471        });
1472    }
1473
1474    pub fn set_background(&mut self, brush: QBrush) {
1475        cpp!(unsafe [self as "QPainter *", brush as "QBrush"] {
1476            self->setBackground(brush);
1477        });
1478    }
1479
1480    pub fn set_brush(&mut self, brush: QBrush) {
1481        cpp!(unsafe [self as "QPainter *", brush as "QBrush"] {
1482            self->setBrush(brush);
1483        });
1484    }
1485
1486    pub fn set_opacity(&mut self, opacity: qreal) {
1487        cpp!(unsafe [self as "QPainter *", opacity as "qreal"] {
1488            self->setOpacity(opacity);
1489        });
1490    }
1491
1492    pub fn set_pen(&mut self, pen: QPen) {
1493        cpp!(unsafe [self as "QPainter *", pen as "QPen"] {
1494            self->setPen(pen);
1495        });
1496    }
1497
1498    pub fn translate(&mut self, offset: QPointF) {
1499        cpp!(unsafe [self as "QPainter *", offset as "QPointF"] {
1500            self->translate(offset);
1501        });
1502    }
1503    pub fn set_render_hint(&mut self, hint: QPainterRenderHint, on: bool) {
1504        cpp!(unsafe [self as "QPainter *", hint as "QPainter::RenderHint", on as "bool"] {
1505            self->setRenderHint(hint, on);
1506        });
1507    }
1508
1509    // void	setBackgroundMode(Qt::BGMode mode)
1510    // void	setCompositionMode(QPainter::CompositionMode mode)
1511    // void	setFont(const QFont &font)
1512}
1513
1514/// Bindings for [`QPainter::RenderHint`][enum] enum.
1515///
1516/// [enum]: https://doc.qt.io/qt-5/qpainter.html#RenderHint-enum
1517#[repr(C)]
1518#[derive(Clone, Copy, PartialEq, Debug)]
1519#[allow(non_camel_case_types)]
1520pub enum QPainterRenderHint {
1521    Antialiasing = 0x01,
1522    TextAntialiasing = 0x02,
1523    SmoothPixmapTransform = 0x04,
1524    HighQualityAntialiasing = 0x08,
1525    NonCosmeticDefaultPen = 0x10,
1526    Qt4CompatiblePainting = 0x20,
1527    LosslessImageRendering = 0x40,
1528}
1529
1530cpp! {{
1531    #include <QtCore/QJsonDocument>
1532    #include <QtCore/QJsonValue>
1533    #include <QtCore/QJsonObject>
1534    #include <QtCore/QJsonArray>
1535}}
1536cpp_class!(
1537    /// Wrapper around [`QJsonValue`][class] class.
1538    ///
1539    /// [class]: https://doc.qt.io/qt-5/qjsonvalue.html
1540    #[derive(Default, PartialEq, Eq, Clone)]
1541    pub unsafe struct QJsonValue as "QJsonValue"
1542);
1543
1544impl Into<QVariant> for QJsonValue {
1545    fn into(self) -> QVariant {
1546        cpp!(unsafe [self as "QJsonValue"] -> QVariant as "QVariant" { return self.toVariant(); })
1547    }
1548}
1549impl From<QVariant> for QJsonValue {
1550    fn from(v: QVariant) -> QJsonValue {
1551        cpp!(unsafe [v as "QVariant"] -> QJsonValue as "QJsonValue" { return QJsonValue::fromVariant(v); })
1552    }
1553}
1554
1555impl Into<QJsonObject> for QJsonValue {
1556    fn into(self) -> QJsonObject {
1557        cpp!(unsafe [self as "QJsonValue"] -> QJsonObject as "QJsonObject" { return self.toObject(); })
1558    }
1559}
1560impl From<QJsonObject> for QJsonValue {
1561    fn from(v: QJsonObject) -> QJsonValue {
1562        cpp!(unsafe [v as "QJsonObject"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1563    }
1564}
1565impl Into<QJsonArray> for QJsonValue {
1566    fn into(self) -> QJsonArray {
1567        cpp!(unsafe [self as "QJsonValue"] -> QJsonArray as "QJsonArray" { return self.toArray(); })
1568    }
1569}
1570impl From<QJsonArray> for QJsonValue {
1571    fn from(v: QJsonArray) -> QJsonValue {
1572        cpp!(unsafe [v as "QJsonArray"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1573    }
1574}
1575
1576impl Into<QString> for QJsonValue {
1577    fn into(self) -> QString {
1578        cpp!(unsafe [self as "QJsonValue"] -> QString as "QString" { return self.toString(); })
1579    }
1580}
1581impl From<QString> for QJsonValue {
1582    fn from(v: QString) -> QJsonValue {
1583        cpp!(unsafe [v as "QString"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1584    }
1585}
1586
1587impl Into<bool> for QJsonValue {
1588    fn into(self) -> bool {
1589        cpp!(unsafe [self as "QJsonValue"] -> bool as "bool" { return self.toBool(); })
1590    }
1591}
1592impl From<bool> for QJsonValue {
1593    fn from(v: bool) -> QJsonValue {
1594        cpp!(unsafe [v as "bool"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1595    }
1596}
1597
1598impl Into<f64> for QJsonValue {
1599    fn into(self) -> f64 {
1600        cpp!(unsafe [self as "QJsonValue"] -> f64 as "double" { return self.toDouble(); })
1601    }
1602}
1603impl From<f64> for QJsonValue {
1604    fn from(v: f64) -> QJsonValue {
1605        cpp!(unsafe [v as "double"] -> QJsonValue as "QJsonValue" { return QJsonValue(v); })
1606    }
1607}
1608
1609#[test]
1610fn test_qjsonvalue() {
1611    let test_str = QJsonValue::from(QVariant::from(QString::from("test")));
1612    let test_str2 = QJsonValue::from(QString::from("test"));
1613    assert!(test_str == test_str2);
1614    assert_eq!(<QJsonValue as Into<QString>>::into(test_str), QString::from("test"));
1615
1616    let test_bool = QJsonValue::from(true);
1617    let test_bool_variant: QVariant = QJsonValue::from(true).into();
1618    let test_bool_variant2 = QVariant::from(true);
1619    assert!(test_bool_variant == test_bool_variant2);
1620    assert_eq!(<QJsonValue as Into<bool>>::into(test_bool), true);
1621
1622    let test_f64 = QJsonValue::from(1.2345);
1623    let test_f64_variant: QVariant = QJsonValue::from(1.2345).into();
1624    let test_f64_variant2 = QVariant::from(1.2345);
1625    assert!(test_f64_variant == test_f64_variant2);
1626    assert_eq!(<QJsonValue as Into<f64>>::into(test_f64), 1.2345);
1627
1628    let values = QJsonArray::from(vec![
1629        QJsonValue::from(QString::from("test")),
1630        QJsonValue::from(true),
1631        QJsonValue::from(false),
1632        QJsonValue::from(1.2345),
1633        QJsonValue::from(456.0),
1634    ]);
1635
1636    assert_eq!(values.to_json().to_string(), "[\"test\",true,false,1.2345,456]");
1637}
1638
1639cpp_class!(
1640    /// Wrapper around [`QJsonObject`][class] class.
1641    ///
1642    /// [class]: https://doc.qt.io/qt-5/qjsonobject.html
1643    #[derive(Default, PartialEq, Eq, Clone)]
1644    pub unsafe struct QJsonObject as "QJsonObject"
1645);
1646
1647impl QJsonObject {
1648    pub fn to_json(&self) -> QByteArray {
1649        cpp!(unsafe [self as "QJsonObject*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Compact); })
1650    }
1651    pub fn to_json_pretty(&self) -> QByteArray {
1652        cpp!(unsafe [self as "QJsonObject*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Indented); })
1653    }
1654    pub fn insert(&mut self, key: &str, value: QJsonValue) {
1655        let len = key.len();
1656        let ptr = key.as_ptr();
1657        cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*", value as "QJsonValue"] { self->insert(QString::fromUtf8(ptr, len), std::move(value)); })
1658    }
1659    pub fn value(&self, key: &str) -> QJsonValue {
1660        let len = key.len();
1661        let ptr = key.as_ptr();
1662        cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] -> QJsonValue as "QJsonValue" { return self->value(QString::fromUtf8(ptr, len)); })
1663    }
1664    pub fn take(&mut self, key: &str) -> QJsonValue {
1665        let len = key.len();
1666        let ptr = key.as_ptr();
1667        cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] -> QJsonValue as "QJsonValue" { return self->take(QString::fromUtf8(ptr, len)); })
1668    }
1669    pub fn remove(&mut self, key: &str) {
1670        let len = key.len();
1671        let ptr = key.as_ptr();
1672        cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] { return self->remove(QString::fromUtf8(ptr, len)); })
1673    }
1674    pub fn len(&self) -> usize {
1675        cpp!(unsafe [self as "QJsonObject*"] -> usize as "size_t" { return self->size(); })
1676    }
1677    pub fn is_empty(&self) -> bool {
1678        cpp!(unsafe [self as "QJsonObject*"] -> bool as "bool" { return self->isEmpty(); })
1679    }
1680    pub fn contains(&self, key: &str) -> bool {
1681        let len = key.len();
1682        let ptr = key.as_ptr();
1683        cpp!(unsafe [self as "QJsonObject*", len as "size_t", ptr as "char*"] -> bool as "bool" { return self->contains(QString::fromUtf8(ptr, len)); })
1684    }
1685    pub fn keys(&self) -> Vec<String> {
1686        let len = self.len();
1687        let mut vec = Vec::with_capacity(len);
1688
1689        let keys = cpp!(unsafe [self as "QJsonObject*"] -> QStringList as "QStringList" { return self->keys(); });
1690
1691        for i in 0..len {
1692            vec.push(keys[i].to_string());
1693        }
1694        vec
1695    }
1696}
1697
1698impl From<HashMap<String, String>> for QJsonObject {
1699    fn from(v: HashMap<String, String>) -> QJsonObject {
1700        let keys: Vec<QString> = v.keys().cloned().map(QString::from).collect();
1701        let values: Vec<QString> = v.values().cloned().map(QString::from).collect();
1702        let keys_ptr = keys.as_ptr();
1703        let values_ptr = values.as_ptr();
1704        let len = keys.len();
1705        cpp!(unsafe [keys_ptr as "const QString*", values_ptr as "const QString*", len as "size_t"] -> QJsonObject as "QJsonObject" {
1706            QJsonObject obj;
1707            for (size_t i = 0; i < len; ++i) {
1708                obj.insert(keys_ptr[i], values_ptr[i]);
1709            }
1710            return obj;
1711        })
1712    }
1713}
1714impl From<HashMap<String, QJsonValue>> for QJsonObject {
1715    fn from(v: HashMap<String, QJsonValue>) -> QJsonObject {
1716        let keys: Vec<QString> = v.keys().cloned().map(QString::from).collect();
1717        let values: Vec<QJsonValue> = v.values().cloned().collect();
1718        let keys_ptr = keys.as_ptr();
1719        let values_ptr = values.as_ptr();
1720        let len = keys.len();
1721        cpp!(unsafe [keys_ptr as "const QString*", values_ptr as "const QJsonValue*", len as "size_t"] -> QJsonObject as "QJsonObject" {
1722            QJsonObject obj;
1723            for (size_t i = 0; i < len; ++i) {
1724                obj.insert(keys_ptr[i], values_ptr[i]);
1725            }
1726            return obj;
1727        })
1728    }
1729}
1730
1731cpp! {{ #include <QtCore/QDebug> }}
1732
1733#[test]
1734fn test_qjsonobject() {
1735    let mut hashmap = HashMap::new();
1736    hashmap.insert("key".to_owned(), "value".to_owned());
1737    hashmap.insert("test".to_owned(), "hello".to_owned());
1738    let object = QJsonObject::from(hashmap);
1739    assert_eq!(object.to_json().to_string(), "{\"key\":\"value\",\"test\":\"hello\"}");
1740
1741    let array = QJsonArray::from(vec![
1742        QJsonValue::from(QString::from("test")),
1743        QJsonValue::from(true),
1744        QJsonValue::from(false),
1745        QJsonValue::from(1.2345),
1746        QJsonValue::from(456.0),
1747    ]);
1748
1749    let mut valuemap = HashMap::new();
1750    valuemap.insert("1_string".to_owned(), QJsonValue::from(QString::from("test")));
1751    valuemap.insert("2_bool".to_owned(), QJsonValue::from(true));
1752    valuemap.insert("3_f64".to_owned(), QJsonValue::from(1.2345));
1753    valuemap.insert("4_int".to_owned(), QJsonValue::from(456.0));
1754    valuemap.insert("5_array".to_owned(), QJsonValue::from(array));
1755    valuemap.insert("6_object".to_owned(), QJsonValue::from(object));
1756    let object = QJsonObject::from(valuemap);
1757    assert_eq!(object.to_json().to_string(), "{\"1_string\":\"test\",\"2_bool\":true,\"3_f64\":1.2345,\"4_int\":456,\"5_array\":[\"test\",true,false,1.2345,456],\"6_object\":{\"key\":\"value\",\"test\":\"hello\"}}");
1758
1759    let at_f64: f64 = object.value("3_f64").into();
1760    assert_eq!(at_f64, 1.2345);
1761
1762    let at_string = object.value("1_string");
1763    assert_eq!(<QJsonValue as Into<QString>>::into(at_string).to_string(), "test");
1764
1765    let mut object = QJsonObject::default();
1766    object.insert("key", QJsonValue::from(QString::from("value")));
1767    object.insert("test", QJsonValue::from(QString::from("hello")));
1768    assert_eq!(object.to_json().to_string(), "{\"key\":\"value\",\"test\":\"hello\"}");
1769
1770    assert_eq!(object.keys(), vec!["key".to_owned(), "test".to_owned()]);
1771}
1772
1773#[test]
1774fn test_qjsonobject_utf8() {
1775    let emoji = String::from("🦀");
1776    let expected = String::from("{\"🦀\":1}");
1777
1778    let mut qmap: QJsonObject = QJsonObject::default();
1779    qmap.insert(&emoji, QVariant::from(1).into());
1780
1781    let actual = qmap.to_json();
1782    let actual = actual.to_str().unwrap();
1783
1784    assert_eq!(actual, expected);
1785}
1786
1787cpp_class!(
1788    /// Wrapper around [`QJsonArray`][class] class.
1789    ///
1790    /// [class]: https://doc.qt.io/qt-5/qjsonarray.html
1791    #[derive(Default, PartialEq, Eq, Clone)]
1792    pub unsafe struct QJsonArray as "QJsonArray"
1793);
1794
1795impl QJsonArray {
1796    pub fn to_json(&self) -> QByteArray {
1797        cpp!(unsafe [self as "QJsonArray*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Compact); })
1798    }
1799    pub fn to_json_pretty(&self) -> QByteArray {
1800        cpp!(unsafe [self as "QJsonArray*"] -> QByteArray as "QByteArray" { return QJsonDocument(*self).toJson(QJsonDocument::Indented); })
1801    }
1802    pub fn push(&mut self, value: QJsonValue) {
1803        cpp!(unsafe [self as "QJsonArray*", value as "QJsonValue"] { self->append(std::move(value)); })
1804    }
1805    pub fn insert(&mut self, index: usize, element: QJsonValue) {
1806        cpp!(unsafe [self as "QJsonArray*", index as "size_t", element as "QJsonValue"] { self->insert(index, std::move(element)); })
1807    }
1808    pub fn at(&self, index: usize) -> QJsonValue {
1809        cpp!(unsafe [self as "QJsonArray*", index as "size_t"] -> QJsonValue as "QJsonValue" { return self->at(index); })
1810    }
1811    pub fn take_at(&mut self, index: usize) -> QJsonValue {
1812        cpp!(unsafe [self as "QJsonArray*", index as "size_t"] -> QJsonValue as "QJsonValue" { return self->takeAt(index); })
1813    }
1814    pub fn remove_at(&mut self, index: usize) {
1815        cpp!(unsafe [self as "QJsonArray*", index as "size_t"] { return self->removeAt(index); })
1816    }
1817    pub fn len(&self) -> usize {
1818        cpp!(unsafe [self as "QJsonArray*"] -> usize as "size_t" { return self->size(); })
1819    }
1820    pub fn is_empty(&self) -> bool {
1821        cpp!(unsafe [self as "QJsonArray*"] -> bool as "bool" { return self->isEmpty(); })
1822    }
1823}
1824
1825impl From<Vec<QJsonValue>> for QJsonArray {
1826    fn from(v: Vec<QJsonValue>) -> QJsonArray {
1827        let ptr = v.as_ptr();
1828        let len = v.len();
1829        cpp!(unsafe [ptr as "const QJsonValue*", len as "size_t"] -> QJsonArray as "QJsonArray" {
1830            QJsonArray arr;
1831            for (size_t i = 0; i < len; ++i) {
1832                arr.append(ptr[i]);
1833            }
1834            return arr;
1835        })
1836    }
1837}
1838
1839#[test]
1840fn test_qjsonarray() {
1841    let mut array = QJsonArray::default();
1842    array.push(QJsonValue::from(QString::from("test")));
1843    array.push(QJsonValue::from(true));
1844    array.push(QJsonValue::from(false));
1845    array.push(QJsonValue::from(1.2345));
1846    assert_eq!(array.to_json().to_string(), "[\"test\",true,false,1.2345]");
1847
1848    let mut vec = Vec::new();
1849    vec.push(QJsonValue::from(QString::from("test")));
1850    vec.push(QJsonValue::from(true));
1851    vec.push(QJsonValue::from(false));
1852    vec.push(QJsonValue::from(1.2345));
1853    assert!(QJsonArray::from(vec) == array);
1854
1855    assert_eq!(array.len(), 4);
1856
1857    assert_eq!(<QJsonValue as Into<QString>>::into(array.at(0)).to_string(), "test");
1858    assert!(array.at(3) == QJsonValue::from(1.2345));
1859}