vim_rs/core/
pc_helpers.rs

1use log::error;
2use super::super::types::vim_any::VimAny;
3use super::client;
4use thiserror::Error;
5use crate::types::structs::{ManagedObjectReference, ObjectSpec, PropertySpec, TraversalSpec};
6
7/// Trait for errors that can be properly boxed and sent across threads
8pub trait BoxableError: std::error::Error + Send + Sync + 'static {}
9
10// Blanket implementation for all types that satisfy the requirements
11impl<E: std::error::Error + Send + Sync + 'static> BoxableError for E {}
12
13/// Error type for Unmarshalling PropertyCollector data into a Rust struct. This is used whenever
14/// the returned data does not match the expected type.
15#[derive(Debug, Error)]
16pub enum Error {
17    #[error("Invalid data type for property {property}. Expected `{expected}` got '{got}'")]
18    InvalidPropertyType{property: String, expected: String, got: String},
19    #[error("Received None for required field '{0}'")]
20    NoneValueForRequiredField(String),
21    #[error("No data found in ObjectUpdate/ObjectContent")]
22    NoDataFound,
23    #[error("Internal Error: {0}")]
24    InternalError(String),
25    #[error("Remote call failure: {0:?}")]
26    RemoteCommunicationError(#[from] client::Error),
27    #[error("Unexpected property path = `{0}`")]
28    UnexpectedPropertyPath(String),
29    #[error("Generic Erorr '{0}'")]
30    GenericError(#[from] Box<dyn std::error::Error + Send + Sync + 'static>),
31    #[error("Lock poisoned: {0}")]
32    PoisonError(String),
33}
34
35pub type Result<T> = std::result::Result<T, Error>;
36
37
38/// Get the type name from a VimAny value. This is used for error reporting.
39pub fn type_name(value :&VimAny) -> String {
40    match value {
41        VimAny::Value(value) => {
42            let type_name : &'static str = value.into();
43            type_name.to_string()
44        },
45        VimAny::Object(obj) => {
46            let type_name : &'static str = obj.data_type().into();
47            type_name.to_string()
48        }
49    }
50}
51
52/// A trait for objects that can be queried using the PropertyCollector utilities. These objects
53/// provide a `PropertySpec` for the object type.
54pub trait Queriable {
55    /// The property spec for this object type.
56    fn prop_spec() -> PropertySpec;
57}
58
59
60type StaticStr = &'static str;
61
62/// Create an ObjectSpec for a view. This is used to specify objects to be monitored from a view.
63pub(crate) fn obj_spec_for_view(view_moref: ManagedObjectReference) -> Vec<ObjectSpec> {
64    let r#type = view_moref.r#type.clone();
65    vec![ObjectSpec {
66        obj: view_moref,
67        skip: Some(false),
68        select_set: Some(vec![Box::new(TraversalSpec {
69            name: Some("traverseEntities".to_string()),
70            r#type: StaticStr::from(r#type).to_string(),
71            path: "view".to_string(),
72            skip: Some(false),
73            select_set: None,
74        })]),
75    }]
76}
77