photonic_interface_grpc_client/
node.rs

1use std::collections::{HashMap, HashSet};
2use std::convert::Infallible;
3use std::fmt;
4use std::str::FromStr;
5use std::sync::Arc;
6
7use anyhow::Result;
8use parking_lot::Mutex;
9use tonic::transport::Channel;
10
11use photonic_interface_grpc_proto::interface_client::InterfaceClient;
12use photonic_interface_grpc_proto::{AttrInfoRequest, AttrName, NodeInfoRequest, NodeInfoResponse};
13
14use crate::attr::Attr;
15use crate::AttrId;
16
17#[derive(Eq, PartialEq, Clone, Hash)]
18pub struct NodeId(pub(crate) String);
19
20impl fmt::Display for NodeId {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        f.write_str(&self.0)
23    }
24}
25
26impl fmt::Debug for NodeId {
27    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28        f.write_str(&self.0)
29    }
30}
31
32impl AsRef<str> for NodeId {
33    fn as_ref(&self) -> &str {
34        return &self.0;
35    }
36}
37
38impl FromStr for NodeId {
39    type Err = Infallible;
40
41    fn from_str(s: &str) -> Result<Self, Self::Err> {
42        return Ok(Self(s.to_owned()));
43    }
44}
45
46pub struct Node {
47    client: Arc<Mutex<InterfaceClient<Channel>>>,
48
49    name: NodeId,
50    kind: String,
51
52    nodes: HashMap<String, NodeId>,
53    attrs: HashSet<AttrId>,
54}
55
56impl Node {
57    pub(crate) fn from_node_info(client: Arc<Mutex<InterfaceClient<Channel>>>, info: NodeInfoResponse) -> Self {
58        let name = NodeId(info.name);
59
60        let nodes = info.nodes.into_iter().map(|(key, node)| (key, NodeId(node))).collect();
61
62        let attrs = info
63            .attrs
64            .into_iter()
65            .map(|attr| AttrId {
66                node: name.clone(),
67                path: vec![attr],
68            })
69            .collect();
70
71        Self {
72            client,
73            name,
74            kind: info.kind,
75            nodes,
76            attrs,
77        }
78    }
79
80    pub fn name(&self) -> &NodeId {
81        return &self.name;
82    }
83
84    pub fn kind(&self) -> &str {
85        return &self.kind;
86    }
87
88    pub fn nodes(&self) -> &HashMap<String, NodeId> {
89        return &self.nodes;
90    }
91
92    pub fn attrs(&self) -> &HashSet<AttrId> {
93        return &self.attrs;
94    }
95
96    pub async fn node(&self, name: &str) -> Result<Option<Node>> {
97        let mut client = self.client.lock_arc();
98
99        let Some(node) = self.nodes.get(name) else {
100            return Ok(None);
101        };
102
103        let response = client
104            .node(NodeInfoRequest {
105                name: node.0.clone(),
106            })
107            .await?
108            .into_inner();
109
110        return Ok(Some(Node::from_node_info(self.client.clone(), response)));
111    }
112
113    pub async fn attr(&self, name: &str) -> Result<Option<Attr>> {
114        let mut client = self.client.lock_arc();
115
116        let response = client
117            .attr(AttrInfoRequest {
118                name: Some(AttrName {
119                    node: self.name.0.clone(),
120                    path: vec![name.to_owned()],
121                }),
122            })
123            .await?
124            .into_inner();
125
126        return Ok(Some(Attr::from_attr_info(self.client.clone(), response)));
127    }
128}