Ver código fonte

poll: parse json data into Model structs

as the values may be null we cannot parse using this form:

    let foo: Foo = serde_json::from_value(bar)

manual_connect is the exception to this as right now we are just parsing
dummy data which is never null.

otherwise if the data is empty we simply write empty values to NodeInfo.
this will be rendered as Null in ui::ui()
lunar-mining 4 anos atrás
pai
commit
70819883e2
3 arquivos alterados com 75 adições e 38 exclusões
  1. 49 24
      bin/dnetview/src/main.rs
  2. 25 12
      bin/dnetview/src/model.rs
  3. 1 2
      bin/dnetview/src/ui.rs

+ 49 - 24
bin/dnetview/src/main.rs

@@ -19,6 +19,7 @@ use std::{
     fs::File,
     io,
     io::Read,
+    net::SocketAddr,
     path::PathBuf,
 };
 use termion::{async_stdin, event::Key, input::TermRead, raw::IntoRawMode};
@@ -30,7 +31,7 @@ use url::Url;
 
 use dnetview::{
     config::{DnvConfig, CONFIG_FILE_CONTENTS},
-    model::{IdList, InfoList, NodeInfo},
+    model::{Channel, IdList, InboundInfo, InfoList, ManualInfo, NodeInfo, OutboundInfo, Slot},
     options::ProgramOptions,
     ui,
     view::{IdListView, InfoListView},
@@ -150,36 +151,60 @@ async fn poll(client: Map, model: Arc<Model>) -> Result<()> {
         debug!("{:?}", reply);
 
         if reply.as_object().is_some() && !reply.as_object().unwrap().is_empty() {
-            //let external_addr = reply.as_object().unwrap().get("external_addr");
-            //let session_inbound = reply.as_object().unwrap().get("session_inbound");
-            //let si_key =
-            //    session_inbound.unwrap().as_object().unwrap().get("key").unwrap().as_u64().unwrap();
+            let ext_addr_option = reply.as_object().unwrap().get("external_addr");
 
-            //let session_manual = reply.as_object().unwrap().get("session_manual");
-            //let sm_key =
-            //    session_manual.unwrap().as_object().unwrap().get("key").unwrap().as_u64().unwrap();
+            let inbound_obj = &reply.as_object().unwrap()["session_inbound"];
+            let manual_obj = &reply.as_object().unwrap()["session_manual"];
+            let outbound_obj = &reply.as_object().unwrap()["session_outbound"];
 
-            //let session_outbound = reply.as_object().unwrap().get("session_outbound");
-            //let so_key =
-            //    session_manual.unwrap().as_object().unwrap().get("key").unwrap().as_u64().unwrap();
+            let mut inconnects = Vec::new();
+            let mut manconnects = Vec::new();
+            let mut outconnects = Vec::new();
+            let mut slots = Vec::new();
 
-            //let channel_state = reply.as_object().unwrap().get("state").unwrap().as_str().unwrap();
-            //let slots = reply.as_object().unwrap().get("slots");
+            // parse inbound connection data
+            let inbound_connected = &inbound_obj["connected"];
 
-            //let session_in = Connection::new(si_key.to_string(), channel_state.to_string());
-            //let session_man = Connection::new(sm_key.to_string(), channel_state.to_string());
-            //let session_out = Connection::new(so_key.to_string(), channel_state.to_string());
+            if !inbound_connected.as_object().unwrap().is_empty() {
+                let inbound_connect: InboundInfo =
+                    serde_json::from_value(inbound_connected.clone())?;
+                inconnects.push(inbound_connect);
+            }
 
-            //let mut outconnects = Vec::new();
-            //let mut inconnects = Vec::new();
-            //let mut manconnects = Vec::new();
+            // parse manual connection data
+            let manual_connect: ManualInfo = serde_json::from_value(manual_obj.clone())?;
+            manconnects.push(manual_connect);
+
+            // parse outbound connection data
+            let outbound_slots = &outbound_obj["slots"];
+
+            for slot in outbound_slots.as_array().unwrap() {
+                if slot["channel"].is_null() {
+                    // channel is empty. initialize with empty values
+                    let state = &slot["state"];
+                    let channel = Channel::new(String::new(), String::new());
+                    let new_slot =
+                        Slot::new(String::new(), channel, state.as_str().unwrap().to_string());
+                    slots.push(new_slot)
+                } else {
+                    // channel is not empty. initialize with whole values
+                    let addr = &slot["addr"];
+                    let state = &slot["state"];
+                    let channel: Channel = serde_json::from_value(slot["channel"].clone())?;
+                    let new_slot = Slot::new(
+                        addr.as_str().unwrap().to_string(),
+                        channel,
+                        state.as_str().unwrap().to_string(),
+                    );
+                    slots.push(new_slot)
+                }
+            }
 
-            //outconnects.push(session_out);
-            //inconnects.push(session_in);
-            //manconnects.push(session_man);
+            let oconnect = OutboundInfo::new(slots);
+            outconnects.push(oconnect);
 
-            //let infos =
-            //    NodeInfo { outbound: outconnects, manual: manconnects, inbound: inconnects };
+            let infos =
+                NodeInfo { outbound: outconnects, manual: manconnects, inbound: inconnects };
 
             //let mut node_info = HashMap::new();
             //// TODO: here we are setting the client url as the ID

+ 25 - 12
bin/dnetview/src/model.rs

@@ -1,6 +1,9 @@
 use async_std::sync::Mutex;
-use std::collections::{HashMap, HashSet};
-use std::net::SocketAddr;
+use serde::Deserialize;
+use std::{
+    collections::{HashMap, HashSet},
+    net::SocketAddr,
+};
 use tui::widgets::ListState;
 
 pub struct Model {
@@ -54,7 +57,7 @@ impl NodeInfo {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Deserialize, Eq, Hash)]
 pub struct ManualInfo {
     pub key: u64,
 }
@@ -65,21 +68,31 @@ impl ManualInfo {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, PartialEq, Deserialize, Eq, Hash)]
 pub struct OutboundInfo {
-    // TODO:  make this a socket addr?
+    slots: Vec<Slot>,
+}
+
+impl OutboundInfo {
+    pub fn new(slots: Vec<Slot>) -> OutboundInfo {
+        OutboundInfo { slots }
+    }
+}
+
+#[derive(Clone, Debug, PartialEq, Deserialize, Eq, Hash)]
+pub struct Slot {
     addr: String,
     channel: Channel,
     state: String,
 }
 
-impl OutboundInfo {
-    pub fn new(addr: String, channel: Channel, state: String) -> OutboundInfo {
-        OutboundInfo { addr, channel, state }
+impl Slot {
+    pub fn new(addr: String, channel: Channel, state: String) -> Slot {
+        Slot { addr, channel, state }
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Hash)]
 pub struct Channel {
     last_msg: String,
     last_status: String,
@@ -91,14 +104,14 @@ impl Channel {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Clone, Deserialize, Debug, PartialEq, Eq, Hash)]
 pub struct InboundInfo {
-    connected: SocketAddr,
+    connected: String,
     channel: Channel,
 }
 
 impl InboundInfo {
-    pub fn new(connected: SocketAddr, channel: Channel) -> InboundInfo {
+    pub fn new(connected: String, channel: Channel) -> InboundInfo {
         InboundInfo { connected, channel }
     }
 }

+ 1 - 2
bin/dnetview/src/ui.rs

@@ -1,5 +1,4 @@
-use crate::view::View;
-use crate::DnvConfig;
+use crate::{view::View, DnvConfig};
 
 use tui::{
     backend::Backend,