1 // Take a look at the license at the top of the repository in the LICENSE file.
2
3 use crate::{resources_register, Resource};
4 use glib::translate::*;
5 use std::env;
6 use std::mem;
7 use std::path::Path;
8 use std::process::Command;
9 use std::ptr;
10
11 impl Resource {
12 #[doc(alias = "g_resource_new_from_data")]
from_data(data: &glib::Bytes) -> Result<Resource, glib::Error>13 pub fn from_data(data: &glib::Bytes) -> Result<Resource, glib::Error> {
14 unsafe {
15 let mut error = ptr::null_mut();
16
17 // Create a copy of data if it is not pointer-aligned
18 // https://bugzilla.gnome.org/show_bug.cgi?id=790030
19 let mut data = data.clone();
20 let data_ptr = glib::ffi::g_bytes_get_data(data.to_glib_none().0, ptr::null_mut());
21 if data_ptr as usize % mem::align_of::<*const u8>() != 0 {
22 data = glib::Bytes::from(&*data);
23 }
24
25 let ret = ffi::g_resource_new_from_data(data.to_glib_none().0, &mut error);
26 if error.is_null() {
27 Ok(from_glib_full(ret))
28 } else {
29 Err(from_glib_full(error))
30 }
31 }
32 }
33 }
34
35 // rustdoc-stripper-ignore-next
36 /// Call from build script to run `glib-compile-resources` to generate compiled gresources to embed
37 /// in binary with [resources_register_include]. `target` is relative to `OUT_DIR`.
38 ///
39 /// ```no_run
40 /// gio::compile_resources(
41 /// "resources",
42 /// "resources/resources.gresource.xml",
43 /// "compiled.gresource",
44 /// );
45 /// ```
compile_resources<P: AsRef<Path>>(source_dir: P, gresource: &str, target: &str)46 pub fn compile_resources<P: AsRef<Path>>(source_dir: P, gresource: &str, target: &str) {
47 let out_dir = env::var("OUT_DIR").unwrap();
48
49 let status = Command::new("glib-compile-resources")
50 .arg("--sourcedir")
51 .arg(source_dir.as_ref())
52 .arg("--target")
53 .arg(&format!("{}/{}", out_dir, target))
54 .arg(gresource)
55 .status()
56 .unwrap();
57
58 if !status.success() {
59 panic!("glib-compile-resources failed with exit status {}", status);
60 }
61
62 println!("cargo:rerun-if-changed={}", gresource);
63 let output = Command::new("glib-compile-resources")
64 .arg("--sourcedir")
65 .arg(source_dir.as_ref())
66 .arg("--generate-dependencies")
67 .arg(gresource)
68 .output()
69 .unwrap()
70 .stdout;
71 let output = String::from_utf8(output).unwrap();
72 for dep in output.split_whitespace() {
73 println!("cargo:rerun-if-changed={}", dep);
74 }
75 }
76
77 #[doc(hidden)]
resources_register_include_impl(bytes: &'static [u8]) -> Result<(), glib::Error>78 pub fn resources_register_include_impl(bytes: &'static [u8]) -> Result<(), glib::Error> {
79 let bytes = glib::Bytes::from_static(bytes);
80 let resource = Resource::from_data(&bytes)?;
81 resources_register(&resource);
82 Ok(())
83 }
84
85 // rustdoc-stripper-ignore-next
86 /// Include gresources generated with [compile_resources] and register with glib. `path` is
87 /// relative to `OUTDIR`.
88 ///
89 /// ```ignore
90 /// gio::resources_register_include!("compiled.gresource").unwrap();
91 /// ```
92 #[macro_export]
93 macro_rules! resources_register_include {
94 ($path:expr) => {
95 $crate::resources_register_include_impl(include_bytes!(concat!(
96 env!("OUT_DIR"),
97 "/",
98 $path
99 )))
100 };
101 }
102