Newer
Older
use petgraph::prelude::DiGraph;
use crate::analyzer::AnalyzerType;
use crate::dottable::Dottable;
use crate::error::OpossumError;
use crate::nodes::NodeGroup;
pub type LightResult = HashMap<String, Option<LightData>>;
type Result<T> = std::result::Result<T, OpossumError>;
/// This is the basic trait that must be implemented by all concrete optical components.
/// Sets the name of this [`Optical`].
fn set_name(&mut self, _name: &str) {}
/// Returns a reference to the name of this [`Optical`].
fn name(&self) -> &str {
/// Return the type of the optical component (lens, filter, ...).
fn node_type(&self) -> &str;
/// Return the available (input & output) ports of this [`Optical`].
fn ports(&self) -> OpticPorts {
OpticPorts::default()
}
/// Perform an analysis of this element. The type of analysis is given by an [`AnalyzerType`].
///
/// This function is normally only called by [`OpticScenery::analyze()`](crate::optic_scenery::OpticScenery::analyze()).
///
/// # Errors
///
/// This function will return an error if internal element-specific errors occur and the analysis cannot be performed.
fn analyze(
&mut self,
_incoming_data: LightResult,
_analyzer_type: &AnalyzerType,
) -> Result<LightResult> {
print!("{}: No analyze function defined.", self.node_type());
Ok(LightResult::default())
}
/// Export analysis data to file with the given name.
fn export_data(&self, _file_name: &str) {
println!(
"no export_data function implemented for nodetype <{}>",
self.node_type()
)
}
/// Returns `true` if the [`Optical`] represents a detector which can report analysis data.
fn is_detector(&self) -> bool {
false
}
/// Mark this [`Optical`] as inverted.
fn set_inverted(&mut self, _inverted: bool) {
// self.ports.set_inverted(inverted);
// self.node.set_inverted(inverted);
}
/// Returns `true` if this [`Optical`] is inverted.
fn inverted(&self) -> bool {
false
}
fn as_group(&self) -> Result<&NodeGroup> {
Err(OpossumError::Other("cannot cast to group".into()))
}
fn set_property(&mut self, _name: &str, _prop: Property) -> Result<()> {
Ok(())
}
}
impl Debug for dyn Optical {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
#[derive(Debug, Default, Clone)]
pub struct OpticGraph(pub DiGraph<OpticRef, Light>);
impl Serialize for OpticGraph {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer {
let g=self.0.clone();
let mut graph=serializer.serialize_struct("graph", 2)?;
let nodes=g.node_weights().map(|n| n.to_owned()).collect::<Vec<OpticRef>>();
graph.serialize_field("nodes", &nodes)?;
let edges=g.edge_weights().map(|n| (n.src_port(),n.target_port()).to_owned()).collect::<Vec<(&str,&str)>>();
graph.serialize_field("edges", &edges)?;
graph.end()
#[derive(Debug, Clone)]
pub struct OpticRef(pub Rc<RefCell<dyn Optical>>);
impl Serialize for OpticRef {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut node = serializer.serialize_struct("node", 1)?;
node.serialize_field("type", self.0.borrow().node_type())?;
node.serialize_field("properties", &self.0.borrow().properties())?;
#[cfg(test)]
mod test {
// #[test]
// #[ignore]
// fn to_dot() {
// let node = OpticNode::new("Test", Dummy::default());
// assert_eq!(
// node.to_dot("i0", "".to_owned()).unwrap(),
// " i0 [label=\"Test\"]\n".to_owned()
// )
// }
// #[test]
// #[ignore]
// fn to_dot_inverted() {
// let mut node = OpticNode::new("Test", Dummy::default());
// node.set_inverted(true);
// assert_eq!(
// node.to_dot("i0", "".to_owned()).unwrap(),
// " i0 [label=\"Test(inv)\"]\n".to_owned()
// )
// }
}