use crate::Error;
use crate::dispids::workspace_object;
use rs_teststand_sys::{Dispatch, Value};
#[derive(Debug)]
pub struct WorkspaceObject {
dispatch: Box<dyn Dispatch>,
}
impl WorkspaceObject {
pub(crate) fn new(dispatch: Box<dyn Dispatch>) -> Self {
Self { dispatch }
}
pub fn display_name(&self) -> Result<String, Error> {
Ok(self
.dispatch
.get(workspace_object::DISPLAY_NAME)?
.into_string()?)
}
pub fn set_display_name(&self, value: &str) -> Result<(), Error> {
self.dispatch.put(
workspace_object::DISPLAY_NAME,
Value::Str(value.to_string()),
)?;
Ok(())
}
pub fn path(&self) -> Result<String, Error> {
Ok(self.dispatch.get(workspace_object::PATH)?.into_string()?)
}
pub fn set_path(&self, value: &str) -> Result<(), Error> {
self.dispatch
.put(workspace_object::PATH, Value::Str(value.to_string()))?;
Ok(())
}
pub fn file_exists(&self) -> Result<bool, Error> {
Ok(self
.dispatch
.get(workspace_object::FILE_EXISTS)?
.as_bool()?)
}
pub fn object_type(&self) -> Result<i32, Error> {
Ok(self.dispatch.get(workspace_object::OBJECT_TYPE)?.as_i32()?)
}
pub fn num_contained_objects(&self) -> Result<i32, Error> {
Ok(self
.dispatch
.get(workspace_object::NUM_CONTAINED_OBJECTS)?
.as_i32()?)
}
pub fn get_contained_object(&self, index: i32) -> Result<Self, Error> {
let dispatch = self
.dispatch
.call(workspace_object::GET_CONTAINED_OBJECT, &[Value::I32(index)])?
.into_object()?;
Ok(Self::new(dispatch))
}
pub fn get_absolute_path(&self) -> Result<String, Error> {
Ok(self
.dispatch
.call(workspace_object::GET_ABSOLUTE_PATH, &[])?
.into_string()?)
}
pub fn new_file(&self, path_string: &str) -> Result<Self, Error> {
let dispatch = self
.dispatch
.call(
workspace_object::NEW_FILE,
&[Value::Str(path_string.to_string())],
)?
.into_object()?;
Ok(Self::new(dispatch))
}
pub fn new_folder(&self, folder_name: &str) -> Result<Self, Error> {
let dispatch = self
.dispatch
.call(
workspace_object::NEW_FOLDER,
&[Value::Str(folder_name.to_string())],
)?
.into_object()?;
Ok(Self::new(dispatch))
}
pub fn remove_object(&self, index: i32) -> Result<Self, Error> {
let dispatch = self
.dispatch
.call(workspace_object::REMOVE_OBJECT, &[Value::I32(index)])?
.into_object()?;
Ok(Self::new(dispatch))
}
}
#[cfg(test)]
mod tests {
use super::WorkspaceObject;
use crate::Error;
use crate::dispids::workspace_object;
use rs_teststand_sys::{ComError, Value};
use std::collections::HashMap;
#[derive(Debug)]
struct FakeDispatch {
responses: HashMap<i32, Value>,
}
impl rs_teststand_sys::Dispatch for FakeDispatch {
fn get(&self, dispid: i32) -> Result<Value, ComError> {
self.responses.get(&dispid).map_or_else(
|| Err(ComError::hresult(0, "fake: unscripted dispid")),
|val| match val {
Value::Str(s) => Ok(Value::Str(s.clone())),
Value::Bool(b) => Ok(Value::Bool(*b)),
Value::I32(n) => Ok(Value::I32(*n)),
_ => Err(ComError::hresult(0, "fake")),
},
)
}
fn put(&self, _dispid: i32, _value: Value) -> Result<(), ComError> {
Err(ComError::hresult(0, "fake"))
}
fn call(&self, _dispid: i32, _args: &[Value]) -> Result<Value, ComError> {
Err(ComError::hresult(0, "fake"))
}
}
#[test]
fn display_name_reads_bstr_property() -> Result<(), Error> {
let fake = FakeDispatch {
responses: HashMap::from([(
workspace_object::DISPLAY_NAME,
Value::Str("MyFolder".to_string()),
)]),
};
let obj = WorkspaceObject::new(Box::new(fake));
assert_eq!(obj.display_name()?, "MyFolder");
Ok(())
}
#[test]
fn num_contained_objects_reads_i4_property() -> Result<(), Error> {
let fake = FakeDispatch {
responses: HashMap::from([(workspace_object::NUM_CONTAINED_OBJECTS, Value::I32(5))]),
};
let obj = WorkspaceObject::new(Box::new(fake));
assert_eq!(obj.num_contained_objects()?, 5);
Ok(())
}
#[test]
fn file_exists_reads_bool_property() -> Result<(), Error> {
let fake = FakeDispatch {
responses: HashMap::from([(workspace_object::FILE_EXISTS, Value::Bool(true))]),
};
let obj = WorkspaceObject::new(Box::new(fake));
assert!(obj.file_exists()?);
Ok(())
}
}