helium_api/models/
hotspot.rs1use super::Dbi;
2use crate::{Error, Result};
3use chrono::{DateTime, Utc};
4
5use serde::{de, Deserialize, Serialize};
6use std::{fmt, str::FromStr};
7
8use super::Geocode;
9
10#[derive(Clone, Serialize, Deserialize, Debug)]
11pub struct Hotspot {
12 pub address: String,
15 pub owner: String,
17 pub name: Option<String>,
20 pub added_height: Option<u64>,
22 pub lat: Option<f64>,
24 pub lng: Option<f64>,
26 pub location: Option<String>,
29 pub mode: HotspotStakingMode,
31 pub elevation: Option<i32>,
33 #[serde(deserialize_with = "Dbi::deserialize_option")]
35 pub gain: Option<Dbi>,
36 pub geocode: Geocode,
38 pub nonce: u64,
40 #[serde(default)]
43 pub speculative_nonce: u64,
44 pub reward_scale: Option<f64>,
46 pub status: Status,
48}
49
50#[derive(Clone, Serialize, Deserialize, Debug)]
51pub struct Status {
52 pub timestamp: Option<DateTime<Utc>>,
54 pub status: Option<String>,
56 pub listen_addrs: Option<Vec<String>>,
58 pub height: Option<u64>,
60}
61
62#[derive(Clone, Serialize, Debug)]
63pub enum HotspotStakingMode {
64 Full,
65 Light,
66 DataOnly,
67}
68
69impl fmt::Display for HotspotStakingMode {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 match self {
72 Self::DataOnly => f.write_str("dataonly"),
73 Self::Full => f.write_str("full"),
74 Self::Light => f.write_str("light"),
75 }
76 }
77}
78
79impl<'de> Deserialize<'de> for HotspotStakingMode {
80 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
81 where
82 D: de::Deserializer<'de>,
83 {
84 struct HotspotStakingModeVisitor;
85
86 impl<'de> de::Visitor<'de> for HotspotStakingModeVisitor {
87 type Value = HotspotStakingMode;
88
89 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
90 formatter.write_str("full, light, dataonly")
91 }
92
93 fn visit_str<E>(self, value: &str) -> std::result::Result<HotspotStakingMode, E>
94 where
95 E: de::Error,
96 {
97 match HotspotStakingMode::from_str(value) {
98 Ok(v) => Ok(v),
99 Err(_) => Err(de::Error::custom("invalid staking mode")),
100 }
101 }
102 }
103
104 deserializer.deserialize_str(HotspotStakingModeVisitor)
105 }
106}
107impl FromStr for HotspotStakingMode {
108 type Err = Error;
109
110 fn from_str(s: &str) -> Result<Self> {
111 match s.to_lowercase().as_ref() {
112 "light" => Ok(Self::Light),
113 "full" => Ok(Self::Full),
114 "dataonly" => Ok(Self::DataOnly),
115 _ => Err(Error::value(s.into())),
116 }
117 }
118}