1use crate::{QObject, QPtr, QString};
2use cpp_core::{DynamicCast, StaticUpcast};
3use std::error::Error;
4use std::fmt;
5
6pub struct FindChildError(FindChildErrorInner);
8
9enum FindChildErrorInner {
10 NotFound {
11 name: String,
12 },
13 TypeMismatch {
14 name: String,
15 target_type: &'static str,
16 },
17}
18
19impl fmt::Display for FindChildError {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 match &self.0 {
22 FindChildErrorInner::NotFound { name } => write!(f, "child \"{}\" not found", name),
23 FindChildErrorInner::TypeMismatch { name, target_type } => write!(
24 f,
25 "child \"{}\" cannot be converted to type {}",
26 name, target_type
27 ),
28 }
29 }
30}
31
32impl fmt::Debug for FindChildError {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 write!(f, "{}", self)
35 }
36}
37
38impl Error for FindChildError {}
39
40impl QObject {
41 pub unsafe fn find_child<T>(&self, name: &str) -> Result<QPtr<T>, FindChildError>
51 where
52 QObject: DynamicCast<T>,
53 T: StaticUpcast<QObject>,
54 {
55 let ptr = self.find_child_q_object_1a(&QString::from_std_str(name));
56 if ptr.is_null() {
57 return Err(FindChildError(FindChildErrorInner::NotFound {
58 name: name.into(),
59 }));
60 }
61
62 let ptr = ptr.dynamic_cast();
63 if ptr.is_null() {
64 return Err(FindChildError(FindChildErrorInner::TypeMismatch {
65 name: name.into(),
66 target_type: std::any::type_name::<T>(),
67 }));
68 }
69 Ok(ptr)
70 }
71}