1#![doc = include_str!("../README.md")]
2
3#[allow(
4 non_snake_case,
5 non_camel_case_types,
6 non_upper_case_globals,
7 dead_code,
8 clippy::all
9)]
10mod bindings;
11pub use bindings::*;
12
13#[cfg(target_os = "windows")]
14impl Default for HWND {
15 fn default() -> Self {
16 Self(std::ptr::null_mut())
17 }
18}
19
20#[cfg(target_os = "windows")]
21impl Default for HINSTANCE {
22 fn default() -> Self {
23 Self(std::ptr::null_mut())
24 }
25}
26
27#[cfg(target_os = "macos")]
28pub const FRAMEWORK_PATH: &str =
29 "Chromium Embedded Framework.framework/Chromium Embedded Framework";
30
31use std::{
32 env::{
33 self,
34 consts::{ARCH, OS},
35 },
36 fs,
37 path::PathBuf,
38};
39
40pub fn get_cef_dir() -> Option<PathBuf> {
41 let cef_path_env = env::var("FLATPAK")
42 .map(|_| String::from("/usr/lib"))
43 .or_else(|_| env::var("CEF_PATH"));
44
45 match cef_path_env {
46 Ok(cef_path) => {
47 PathBuf::from(cef_path).canonicalize().ok()
49 }
50 Err(_) => {
51 let out_dir = PathBuf::from(env!("OUT_DIR"));
52 let cef_dir = format!("cef_{OS}_{ARCH}");
53 let cef_dir = out_dir.join(&cef_dir).canonicalize().ok()?;
54 fs::exists(&cef_dir).ok()?.then_some(cef_dir)
55 }
56 }
57}
58
59#[cfg(test)]
60mod test {
61 use super::*;
62
63 #[test]
64 fn test_cef_dir() {
65 let _ = get_cef_dir().expect("CEF not found");
66 }
67
68 #[test]
69 fn test_init() {
70 use std::ptr::*;
71
72 unsafe {
73 #[cfg(target_os = "macos")]
74 {
75 use std::os::unix::ffi::OsStrExt;
76
77 let cef_dir = get_cef_dir().expect("CEF not found");
78 let framework_dir = cef_dir
79 .join(FRAMEWORK_PATH)
80 .canonicalize()
81 .expect("failed to get framework path");
82 let framework_dir = std::ffi::CString::new(framework_dir.as_os_str().as_bytes())
83 .expect("invalid path");
84
85 assert_eq!(cef_load_library(framework_dir.as_ptr().cast()), 1);
86 }
87
88 assert_eq!(cef_initialize(null(), null(), null_mut(), null_mut()), 0);
89 };
90 }
91}