diff --git a/cairo/Cargo.toml b/cairo/Cargo.toml index bfc13ebe06c5..782436f3bb0b 100644 --- a/cairo/Cargo.toml +++ b/cairo/Cargo.toml @@ -6,7 +6,7 @@ authors = ["The gtk-rs Project Developers"] keywords = ["cairo", "gtk-rs", "gnome", "GUI"] readme = "README.md" documentation = "https://gtk-rs.org/gtk-rs-core/stable/latest/docs/cairo/" -version = "0.16.4" +version = "0.16.5" description = "Rust bindings for the Cairo library" repository = "https://github.com/gtk-rs/gtk-rs-core" edition = "2021" diff --git a/cairo/sys/Cargo.toml b/cairo/sys/Cargo.toml index 11c2100cbeb1..bb907e34197b 100644 --- a/cairo/sys/Cargo.toml +++ b/cairo/sys/Cargo.toml @@ -4,7 +4,7 @@ license = "MIT" authors = ["The gtk-rs Project Developers"] homepage = "https://gtk-rs.org/" description = "FFI bindings to libcairo" -version = "0.16.4" +version = "0.16.5" keywords = ["cairo", "ffi", "gtk-rs", "gnome"] repository = "https://github.com/gtk-rs/gtk-rs-core" build = "build.rs" diff --git a/gdk-pixbuf/Cargo.toml b/gdk-pixbuf/Cargo.toml index 717ac28bf511..45f4ea5a29ec 100644 --- a/gdk-pixbuf/Cargo.toml +++ b/gdk-pixbuf/Cargo.toml @@ -6,7 +6,7 @@ authors = ["The gtk-rs Project Developers"] keywords = ["gdk-pixbuf", "gtk-rs", "gnome"] readme = "README.md" documentation = "https://gtk-rs.org/gtk-rs-core/stable/latest/docs/gdk_pixbuf/" -version = "0.16.4" +version = "0.16.5" description = "Rust bindings for the GdkPixbuf library" repository = "https://github.com/gtk-rs/gtk-rs-core" exclude = [ diff --git a/gdk-pixbuf/sys/Cargo.toml b/gdk-pixbuf/sys/Cargo.toml index 855ae6b69ccc..18fc359d5465 100644 --- a/gdk-pixbuf/sys/Cargo.toml +++ b/gdk-pixbuf/sys/Cargo.toml @@ -40,7 +40,7 @@ keywords = ["gdk-pixbuf", "ffi", "gtk-rs", "gnome"] license = "MIT" name = "gdk-pixbuf-sys" repository = "https://github.com/gtk-rs/gtk-rs-core" -version = "0.16.4" +version = "0.16.5" edition = "2021" rust-version = "1.63" [package.metadata.docs.rs] diff --git a/gio/Cargo.toml b/gio/Cargo.toml index 5e323af7bfe1..bd0c1e3bcc27 100644 --- a/gio/Cargo.toml +++ b/gio/Cargo.toml @@ -6,7 +6,7 @@ authors = ["The gtk-rs Project Developers"] keywords = ["glib", "gio", "gtk-rs", "gnome"] readme = "README.md" documentation = "https://gtk-rs.org/gtk-rs-core/stable/latest/docs/gio/" -version = "0.16.4" +version = "0.16.5" description = "Rust bindings for the Gio library" repository = "https://github.com/gtk-rs/gtk-rs-core" exclude = [ diff --git a/gio/sys/Cargo.toml b/gio/sys/Cargo.toml index b90c526d1274..881d929e66b8 100644 --- a/gio/sys/Cargo.toml +++ b/gio/sys/Cargo.toml @@ -45,7 +45,7 @@ keywords = ["gio", "ffi", "gtk-rs", "gnome"] license = "MIT" name = "gio-sys" repository = "https://github.com/gtk-rs/gtk-rs-core" -version = "0.16.4" +version = "0.16.5" edition = "2021" rust-version = "1.63" [package.metadata.docs.rs] diff --git a/glib-build-tools/Cargo.toml b/glib-build-tools/Cargo.toml index dda91dac951b..9a8ddad6e99e 100644 --- a/glib-build-tools/Cargo.toml +++ b/glib-build-tools/Cargo.toml @@ -6,7 +6,7 @@ authors = ["The gtk-rs Project Developers"] keywords = ["glib", "gio", "gtk-rs", "gnome", "build-dependencies"] readme = "README.md" documentation = "https://gtk-rs.org/gtk-rs-core/stable/latest/docs/glib-build-tools" -version = "0.16.4" +version = "0.16.5" description = "Rust bindings for the Gio library, build script utils crate" repository = "https://github.com/gtk-rs/gtk-rs-core" edition = "2021" diff --git a/glib-macros/Cargo.toml b/glib-macros/Cargo.toml index f0eead402e47..ab9775448159 100644 --- a/glib-macros/Cargo.toml +++ b/glib-macros/Cargo.toml @@ -4,7 +4,7 @@ documentation = "https://gtk-rs.org/gtk-rs-core/stable/latest/docs/glib_macros/" homepage = "https://gtk-rs.org/" authors = ["The gtk-rs Project Developers"] description = "Rust bindings for the GLib library, proc macros crate" -version = "0.16.4" +version = "0.16.5" keywords = ["glib", "gtk-rs", "gnome", "GUI"] repository = "https://github.com/gtk-rs/gtk-rs-core" license = "MIT" diff --git a/glib/Cargo.toml b/glib/Cargo.toml index b91632b70a2c..6ca1b12267be 100644 --- a/glib/Cargo.toml +++ b/glib/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://gtk-rs.org/" authors = ["The gtk-rs Project Developers"] description = "Rust bindings for the GLib library" readme = "README.md" -version = "0.16.4" +version = "0.16.5" keywords = ["glib", "gtk-rs", "gnome", "GUI"] repository = "https://github.com/gtk-rs/gtk-rs-core" license = "MIT" diff --git a/glib/gobject-sys/Cargo.toml b/glib/gobject-sys/Cargo.toml index d5e92abd6ad7..17af19fd7052 100644 --- a/glib/gobject-sys/Cargo.toml +++ b/glib/gobject-sys/Cargo.toml @@ -35,7 +35,7 @@ keywords = ["gobject", "ffi", "gtk-rs", "gnome"] license = "MIT" name = "gobject-sys" repository = "https://github.com/gtk-rs/gtk-rs-core" -version = "0.16.4" +version = "0.16.5" edition = "2021" rust-version = "1.63" [package.metadata.docs.rs] diff --git a/glib/src/lib.rs b/glib/src/lib.rs index 027ff38e4b19..da582bb65ebb 100644 --- a/glib/src/lib.rs +++ b/glib/src/lib.rs @@ -29,8 +29,8 @@ pub use self::bytes::Bytes; pub use self::closure::{Closure, RustClosure}; pub use self::error::{BoolError, Error}; pub use self::object::{ - BorrowedObject, Cast, Class, InitiallyUnowned, Interface, IsA, Object, ObjectExt, ObjectType, - SendWeakRef, WeakRef, + BorrowedObject, Cast, CastNone, Class, InitiallyUnowned, Interface, IsA, Object, ObjectExt, + ObjectType, SendWeakRef, WeakRef, }; pub use self::signal::{ signal_handler_block, signal_handler_disconnect, signal_handler_unblock, diff --git a/glib/src/object.rs b/glib/src/object.rs index 749745eb185c..ecfd7f4dc9f7 100644 --- a/glib/src/object.rs +++ b/glib/src/object.rs @@ -288,6 +288,79 @@ pub trait Cast: ObjectType { impl Cast for T {} +// rustdoc-stripper-ignore-next +/// Convenience trait mirroring `Cast`, implemented on `Option` types. +/// +/// # Warning +/// Inveitably this trait will discard informations about a downcast failure: +/// you don't know if the object was not of the expected type, or if it was `None`. +/// If you need to handle the downcast error, use `Cast` over a `glib::Object`. +/// +/// # Example +/// ```ignore +/// let widget: Option = list_item.child(); +/// +/// // Without using `CastNone` +/// let label = widget.unwrap().downcast::().unwrap(); +/// +/// // Using `CastNone` we can avoid the first `unwrap()` call +/// let label = widget.and_downcast::().unwrap(); +/// ```` +pub trait CastNone: Sized { + type Inner; + fn and_downcast(self) -> Option + where + Self::Inner: CanDowncast; + fn and_downcast_ref(&self) -> Option<&T> + where + Self::Inner: CanDowncast; + fn and_upcast(self) -> Option + where + Self::Inner: IsA; + fn and_upcast_ref(&self) -> Option<&T> + where + Self::Inner: IsA; + fn and_dynamic_cast(self) -> Result; + fn and_dynamic_cast_ref(&self) -> Option<&T>; +} +impl CastNone for Option { + type Inner = I; + + fn and_downcast(self) -> Option + where + Self::Inner: CanDowncast, + { + self.and_then(|i| i.downcast().ok()) + } + + fn and_downcast_ref(&self) -> Option<&T> + where + Self::Inner: CanDowncast, + { + self.as_ref().and_then(|i| i.downcast_ref()) + } + fn and_upcast(self) -> Option + where + Self::Inner: IsA, + { + self.map(|i| i.upcast()) + } + + fn and_upcast_ref(&self) -> Option<&T> + where + Self::Inner: IsA, + { + self.as_ref().map(|i| i.upcast_ref()) + } + fn and_dynamic_cast(self) -> Result { + self.ok_or(None) + .and_then(|i| i.dynamic_cast().map_err(|e| Some(e))) + } + fn and_dynamic_cast_ref(&self) -> Option<&T> { + self.as_ref().and_then(|i| i.dynamic_cast_ref()) + } +} + // rustdoc-stripper-ignore-next /// Marker trait for the statically known possibility of downcasting from `Self` to `T`. pub trait CanDowncast {} diff --git a/glib/src/prelude.rs b/glib/src/prelude.rs index 1d2b14b433d3..9e3540a25ac4 100644 --- a/glib/src/prelude.rs +++ b/glib/src/prelude.rs @@ -5,6 +5,6 @@ pub use crate::param_spec::ParamSpecBuilderExt; pub use crate::{ - Cast, Continue, IsA, ObjectExt, ObjectType, ParamSpecType, StaticType, StaticTypeExt, + Cast, CastNone, Continue, IsA, ObjectExt, ObjectType, ParamSpecType, StaticType, StaticTypeExt, StaticVariantType, ToSendValue, ToValue, ToVariant, }; diff --git a/glib/sys/Cargo.toml b/glib/sys/Cargo.toml index 26cbbf87f087..5999c284a1c8 100644 --- a/glib/sys/Cargo.toml +++ b/glib/sys/Cargo.toml @@ -32,7 +32,7 @@ keywords = ["glib", "ffi", "gtk-rs", "gnome"] license = "MIT" name = "glib-sys" repository = "https://github.com/gtk-rs/gtk-rs-core" -version = "0.16.4" +version = "0.16.5" edition = "2021" rust-version = "1.63" [package.metadata.docs.rs] diff --git a/graphene/Cargo.toml b/graphene/Cargo.toml index fcb947fa309a..5f48de80ec10 100644 --- a/graphene/Cargo.toml +++ b/graphene/Cargo.toml @@ -6,7 +6,7 @@ authors = ["The gtk-rs Project Developers"] keywords = ["graphene", "graphene-rs", "gtk-rs", "gnome", "GUI"] readme = "README.md" documentation = "https://gtk-rs.org/gtk-rs-core/stable/latest/docs/graphene/" -version = "0.16.4" +version = "0.16.5" description = "Rust bindings for the Graphene library" repository = "https://github.com/gtk-rs/gtk-rs-core" exclude = [ diff --git a/graphene/sys/Cargo.toml b/graphene/sys/Cargo.toml index 4aa81db7d10b..1818248192e4 100644 --- a/graphene/sys/Cargo.toml +++ b/graphene/sys/Cargo.toml @@ -29,7 +29,7 @@ keywords = ["graphene", "ffi", "gtk-rs", "gnome"] license = "MIT" name = "graphene-sys" repository = "https://github.com/gtk-rs/gtk-rs-core" -version = "0.16.4" +version = "0.16.5" edition = "2021" rust-version = "1.63" [package.metadata.docs.rs] diff --git a/pango/Cargo.toml b/pango/Cargo.toml index dde787015755..3a8d6f34c91e 100644 --- a/pango/Cargo.toml +++ b/pango/Cargo.toml @@ -5,7 +5,7 @@ homepage = "https://gtk-rs.org/" authors = ["The gtk-rs Project Developers"] keywords = ["pango", "gtk-rs", "gnome"] readme = "README.md" -version = "0.16.4" +version = "0.16.5" description = "Rust bindings for the Pango library" repository = "https://github.com/gtk-rs/gtk-rs-core" license = "MIT" diff --git a/pango/Gir.toml b/pango/Gir.toml index 9cc92908cc1a..0dfc1dfa6eeb 100644 --- a/pango/Gir.toml +++ b/pango/Gir.toml @@ -69,7 +69,6 @@ manual = [ "Pango.Coverage", "Pango.GlyphGeometry", "Pango.GlyphInfo", - "Pango.Language", "Pango.LayoutDeserializeError", "Pango.Rectangle", ] @@ -332,6 +331,26 @@ concurrency = "send+sync" name = "glyphs" const = true +[[object]] +name = "Pango.Language" +status = "generate" + [[object.function]] + pattern = "get_(scripts|preferred)" + manual = true # probably needs annotation fixes upstream (array zero-terminated=1) + [[object.function]] + pattern = "(get_sample_string|includes_script|matches|to_string)" + [[object.function.parameter]] + name = "language" + const = true + [[object.function]] + name = "from_string" + # This only returns NULL when passing NULL + [[object.function.parameter]] + name = "language" + nullable = false + [object.function.return] + nullable = false + [[object]] name = "Pango.Layout" status = "generate" diff --git a/pango/src/attr_language.rs b/pango/src/attr_language.rs index 820756d2072d..6720fa4c4e41 100644 --- a/pango/src/attr_language.rs +++ b/pango/src/attr_language.rs @@ -8,7 +8,11 @@ define_attribute_struct!(AttrLanguage, ffi::PangoAttrLanguage, &[AttrType::Langu impl AttrLanguage { #[doc(alias = "pango_attr_language_new")] pub fn new(language: &Language) -> Self { - unsafe { from_glib_full(ffi::pango_attr_language_new(language.to_glib_none().0)) } + unsafe { + from_glib_full(ffi::pango_attr_language_new(mut_override( + language.to_glib_none().0, + ))) + } } pub fn value(&self) -> Language { diff --git a/pango/src/auto/language.rs b/pango/src/auto/language.rs new file mode 100644 index 000000000000..040cbca28318 --- /dev/null +++ b/pango/src/auto/language.rs @@ -0,0 +1,79 @@ +// This file was generated by gir (https://github.com/gtk-rs/gir) +// from gir-files (https://github.com/gtk-rs/gir-files) +// DO NOT EDIT + +use crate::Script; +use glib::translate::*; +use std::fmt; + +glib::wrapper! { + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct Language(Boxed); + + match fn { + copy => |ptr| glib::gobject_ffi::g_boxed_copy(ffi::pango_language_get_type(), ptr as *mut _) as *mut ffi::PangoLanguage, + free => |ptr| glib::gobject_ffi::g_boxed_free(ffi::pango_language_get_type(), ptr as *mut _), + type_ => || ffi::pango_language_get_type(), + } +} + +impl Language { + #[doc(alias = "pango_language_get_sample_string")] + #[doc(alias = "get_sample_string")] + pub fn sample_string(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::pango_language_get_sample_string(mut_override( + self.to_glib_none().0, + ))) + } + } + + #[doc(alias = "pango_language_includes_script")] + pub fn includes_script(&self, script: Script) -> bool { + unsafe { + from_glib(ffi::pango_language_includes_script( + mut_override(self.to_glib_none().0), + script.into_glib(), + )) + } + } + + #[doc(alias = "pango_language_matches")] + pub fn matches(&self, range_list: &str) -> bool { + unsafe { + from_glib(ffi::pango_language_matches( + mut_override(self.to_glib_none().0), + range_list.to_glib_none().0, + )) + } + } + + #[doc(alias = "pango_language_to_string")] + #[doc(alias = "to_string")] + pub fn to_str(&self) -> glib::GString { + unsafe { + from_glib_none(ffi::pango_language_to_string(mut_override( + self.to_glib_none().0, + ))) + } + } + + #[doc(alias = "pango_language_from_string")] + pub fn from_string(language: &str) -> Language { + unsafe { from_glib_none(ffi::pango_language_from_string(language.to_glib_none().0)) } + } + + #[doc(alias = "pango_language_get_default")] + #[doc(alias = "get_default")] + #[allow(clippy::should_implement_trait)] + pub fn default() -> Language { + unsafe { from_glib_none(ffi::pango_language_get_default()) } + } +} + +impl fmt::Display for Language { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str(&self.to_str()) + } +} diff --git a/pango/src/auto/mod.rs b/pango/src/auto/mod.rs index b3800971830b..b259858bcf6e 100644 --- a/pango/src/auto/mod.rs +++ b/pango/src/auto/mod.rs @@ -53,6 +53,9 @@ pub use self::glyph_string::GlyphString; mod item; pub use self::item::Item; +mod language; +pub use self::language::Language; + mod layout_iter; pub use self::layout_iter::LayoutIter; diff --git a/pango/src/language.rs b/pango/src/language.rs index 452248c1f5ca..6d193116985f 100644 --- a/pango/src/language.rs +++ b/pango/src/language.rs @@ -1,104 +1,14 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use crate::Script; -use glib::translate::*; -use glib::GString; +use std::str::FromStr; -#[doc(alias = "PangoLanguage")] -pub struct Language(*mut ffi::PangoLanguage); +use crate::{Language, Script}; +use glib::translate::*; unsafe impl Send for Language {} unsafe impl Sync for Language {} -#[doc(hidden)] -impl<'a> ToGlibPtr<'a, *mut ffi::PangoLanguage> for &'a Language { - type Storage = &'a Language; - - fn to_glib_none(&self) -> Stash<'a, *mut ffi::PangoLanguage, Self> { - Stash(self.0, *self) - } -} - -#[doc(hidden)] -impl<'a> ToGlibPtrMut<'a, *mut ffi::PangoLanguage> for Language { - type Storage = &'a mut Self; - - #[inline] - fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ffi::PangoLanguage, Self> { - StashMut(self.0, self) - } -} - -#[doc(hidden)] -impl FromGlibPtrNone<*mut ffi::PangoLanguage> for Language { - unsafe fn from_glib_none(ptr: *mut ffi::PangoLanguage) -> Self { - assert!(!ptr.is_null()); - Self(ptr) - } -} - -#[doc(hidden)] -impl FromGlibPtrFull<*mut ffi::PangoLanguage> for Language { - unsafe fn from_glib_full(ptr: *mut ffi::PangoLanguage) -> Self { - assert!(!ptr.is_null()); - Self(ptr) - } -} - -#[doc(hidden)] -impl FromGlibPtrNone<*const ffi::PangoLanguage> for Language { - unsafe fn from_glib_none(ptr: *const ffi::PangoLanguage) -> Self { - assert!(!ptr.is_null()); - Self(ptr as *mut _) - } -} - -#[doc(hidden)] -impl FromGlibPtrFull<*const ffi::PangoLanguage> for Language { - unsafe fn from_glib_full(ptr: *const ffi::PangoLanguage) -> Self { - assert!(!ptr.is_null()); - Self(ptr as *mut _) - } -} - -impl Default for Language { - #[doc(alias = "pango_language_get_default")] - fn default() -> Self { - unsafe { from_glib_full(ffi::pango_language_get_default()) } - } -} - impl Language { - #[doc(alias = "pango_language_from_string")] - pub fn from_string(language: &str) -> Self { - unsafe { from_glib_full(ffi::pango_language_from_string(language.to_glib_none().0)) } - } - - #[doc(alias = "pango_language_to_string")] - pub fn to_string(&self) -> GString { - unsafe { from_glib_none(ffi::pango_language_to_string(self.to_glib_none().0)) } - } - - #[doc(alias = "pango_language_matches")] - pub fn matches(&self, range_list: &str) -> bool { - unsafe { - from_glib(ffi::pango_language_matches( - self.to_glib_none().0, - range_list.to_glib_none().0, - )) - } - } - - #[doc(alias = "pango_language_includes_script")] - pub fn includes_script(&self, script: Script) -> bool { - unsafe { - from_glib(ffi::pango_language_includes_script( - self.to_glib_none().0, - script.into_glib(), - )) - } - } - #[doc(alias = "get_scripts")] #[doc(alias = "pango_language_get_scripts")] pub fn scripts(&self) -> Vec