diff --git a/Cargo.lock b/Cargo.lock
index eaf147a630cd184cff9cc21e6c908704b28b6495..8f4800815053f86edf283e040e7395d0e13a9ef2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -476,6 +476,7 @@ dependencies = [
"durs-common-tools 0.1.0",
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pest 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/lib/tools/network-documents/Cargo.toml b/lib/tools/network-documents/Cargo.toml
index d9125a63cf5288ee0afcc6a51b7525de6e0bf0eb..ea1047e0e75036519feb88f87f24aa5daa74f4e7 100644
--- a/lib/tools/network-documents/Cargo.toml
+++ b/lib/tools/network-documents/Cargo.toml
@@ -24,7 +24,8 @@ serde = { version = "1.0.*", features = ["derive"] }
serde_json = "1.0.*"
[dev-dependencies]
-pretty_assertions = "0.5.1"
bincode = "1.0.1"
+maplit = "1.0.1"
+pretty_assertions = "0.5.1"
[features]
\ No newline at end of file
diff --git a/lib/tools/network-documents/src/lib.rs b/lib/tools/network-documents/src/lib.rs
index 7cb75283ff74e122c1142a085efffb0d08f95b5d..19d933a5a9234d89d205051ff96a51b5c21c3b59 100644
--- a/lib/tools/network-documents/src/lib.rs
+++ b/lib/tools/network-documents/src/lib.rs
@@ -177,7 +177,7 @@ mod tests {
EndpointV1::parse_from_raw("WS2P c1c39a0a i3.ifee.fr 80 /ws2p", issuer, 0, 0),
Ok(EndpointV1 {
issuer,
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
node_id: Some(node_id),
hash_full_id: Some(full_id.sha256()),
host: String::from("i3.ifee.fr"),
@@ -202,7 +202,7 @@ mod tests {
EndpointV1::parse_from_raw("WS2P cb06a19b g1.imirhil.fr 53012", issuer, 0, 0),
Ok(EndpointV1 {
issuer,
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
node_id: Some(node_id),
hash_full_id: Some(full_id.sha256()),
host: String::from("g1.imirhil.fr"),
diff --git a/lib/tools/network-documents/src/network_endpoint.rs b/lib/tools/network-documents/src/network_endpoint.rs
index 2ceef9ba01a9179dd804f2fce82d5fb0d3ba6dc1..99665280e088559e9389b4d17502c4836043a005 100644
--- a/lib/tools/network-documents/src/network_endpoint.rs
+++ b/lib/tools/network-documents/src/network_endpoint.rs
@@ -21,6 +21,7 @@ use dup_crypto::keys::PubKey;
use hex;
use pest::iterators::Pair;
use pest::Parser;
+use std::collections::HashSet;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
@@ -61,13 +62,41 @@ impl ApiFeatures {
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
/// Identifies the API of an endpoint
-pub struct NetworkEndpointApi(pub String);
+pub struct ApiName(pub String);
+
+/// Api version
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+pub struct ApiVersion(pub usize);
+
+/// Api parts
+#[derive(Clone, Debug)]
+pub struct ApiPart {
+ pub name: ApiName,
+ pub versions: HashSet<ApiVersion>,
+}
+
+impl ApiPart {
+ pub fn union_exist(&self, other: &Self) -> bool {
+ if self.name == other.name {
+ self.versions.intersection(&other.versions).count() > 0
+ } else {
+ false
+ }
+ }
+ pub fn contains(&self, api_name: &ApiName, api_version: ApiVersion) -> bool {
+ if self.name == *api_name {
+ self.versions.contains(&api_version)
+ } else {
+ false
+ }
+ }
+}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
/// Endpoint v1
pub struct EndpointV1 {
/// API Name
- pub api: NetworkEndpointApi,
+ pub api: ApiName,
/// Node unique identifier
pub node_id: Option<NodeId>,
/// Public key of the node declaring this endpoint
@@ -152,7 +181,7 @@ impl EndpointV1 {
}
EndpointV1 {
issuer,
- api: NetworkEndpointApi(String::from(api_name)),
+ api: ApiName(String::from(api_name)),
node_id,
hash_full_id,
host: String::from(host_str),
@@ -259,7 +288,7 @@ pub struct Endpoint {
/// Endpoint v2
pub struct EndpointV2 {
/// API Name
- pub api: NetworkEndpointApi,
+ pub api: ApiName,
/// API version
pub api_version: u16,
/// Network features
@@ -395,7 +424,7 @@ impl EndpointV2 {
network_features = EndpointV2NetworkFeatures(vec![]);
}
EndpointV2 {
- api: NetworkEndpointApi(String::from(api_str)),
+ api: ApiName(String::from(api_str)),
api_version,
network_features,
api_features,
@@ -437,12 +466,18 @@ impl ToString for EndpointEnum {
impl EndpointEnum {
/// Accessors providing API name
- pub fn api(&self) -> NetworkEndpointApi {
+ pub fn api(&self) -> ApiName {
match *self {
EndpointEnum::V1(ref ep) => ep.api.clone(),
EndpointEnum::V2(ref ep) => ep.api.clone(),
}
}
+ pub fn version(&self) -> ApiVersion {
+ match *self {
+ EndpointEnum::V1(_) => ApiVersion(1),
+ EndpointEnum::V2(_) => ApiVersion(2),
+ }
+ }
/// Accessors providing node unique identifier
pub fn node_uuid(&self) -> Option<NodeId> {
match *self {
@@ -526,6 +561,64 @@ impl EndpointEnum {
mod tests {
use super::*;
use bincode::{deserialize, serialize};
+ use maplit::hashset;
+
+ #[inline]
+ fn api_part_1() -> ApiPart {
+ ApiPart {
+ name: ApiName("api1".to_owned()),
+ versions: hashset![ApiVersion(1)],
+ }
+ }
+
+ #[test]
+ fn test_api_part_contains() {
+ let api_part = api_part_1();
+
+ assert_eq!(
+ true,
+ api_part.contains(&ApiName("api1".to_owned()), ApiVersion(1))
+ );
+
+ assert_eq!(
+ false,
+ api_part.contains(&ApiName("api1".to_owned()), ApiVersion(2))
+ );
+
+ assert_eq!(
+ false,
+ api_part.contains(&ApiName("api2".to_owned()), ApiVersion(1))
+ );
+ }
+
+ #[test]
+ fn test_api_part_union_exist() {
+ let api_part = api_part_1();
+
+ assert_eq!(
+ false,
+ api_part.union_exist(&ApiPart {
+ name: ApiName("api2".to_owned()),
+ versions: hashset![ApiVersion(1)],
+ })
+ );
+
+ assert_eq!(
+ false,
+ api_part.union_exist(&ApiPart {
+ name: ApiName("api1".to_owned()),
+ versions: hashset![ApiVersion(2), ApiVersion(3)],
+ })
+ );
+
+ assert_eq!(
+ true,
+ api_part.union_exist(&ApiPart {
+ name: ApiName("api1".to_owned()),
+ versions: hashset![ApiVersion(1), ApiVersion(2)],
+ })
+ );
+ }
#[test]
fn test_network_features() {
@@ -575,7 +668,7 @@ mod tests {
fn test_parse_and_read_minimal_endpoint() {
let str_endpoint = "UNKNOWN_API 8080";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("UNKNOWN_API")),
+ api: ApiName(String::from("UNKNOWN_API")),
api_version: 0,
network_features: EndpointV2NetworkFeatures(vec![]),
api_features: ApiFeatures(vec![]),
@@ -592,7 +685,7 @@ mod tests {
fn test_parse_and_read_localhost_endpoint() {
let str_endpoint = "WS2P localhost 10900";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 0,
network_features: EndpointV2NetworkFeatures(vec![]),
api_features: ApiFeatures(vec![]),
@@ -614,7 +707,7 @@ mod tests {
fn test_parse_and_read_classic_v1_endpoint() {
let str_endpoint = "ES_CORE_API g1.data.duniter.fr 443";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("ES_CORE_API")),
+ api: ApiName(String::from("ES_CORE_API")),
api_version: 0,
network_features: EndpointV2NetworkFeatures(vec![]),
api_features: ApiFeatures(vec![]),
@@ -631,7 +724,7 @@ mod tests {
fn test_parse_and_read_endpoint_with_host() {
let str_endpoint = "WS2P V2 S 7 g1.durs.ifee.fr 443 ws2p";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 2,
network_features: EndpointV2NetworkFeatures(vec![4u8]),
api_features: ApiFeatures(vec![7u8]),
@@ -653,7 +746,7 @@ mod tests {
fn test_parse_and_read_endpoint_with_ipv4() {
let str_endpoint = "WS2P V2 S 7 84.16.72.210 443 ws2p";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 2,
network_features: EndpointV2NetworkFeatures(vec![4u8]),
api_features: ApiFeatures(vec![7u8]),
@@ -670,7 +763,7 @@ mod tests {
fn test_parse_and_read_endpoint_with_ipv6() {
let str_endpoint = "WS2P V2 S 7 [2001:41d0:8:c5aa::1] 443 ws2p";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 2,
network_features: EndpointV2NetworkFeatures(vec![4u8]),
api_features: ApiFeatures(vec![7u8]),
@@ -687,7 +780,7 @@ mod tests {
fn test_parse_and_read_endpoint_with_ipv4_and_ip_v6() {
let str_endpoint = "WS2P V2 S 7 5.135.188.170 [2001:41d0:8:c5aa::1] 443 ws2p";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 2,
network_features: EndpointV2NetworkFeatures(vec![4u8]),
api_features: ApiFeatures(vec![7u8]),
@@ -704,7 +797,7 @@ mod tests {
fn test_parse_and_read_endpoint_with_all_fields() {
let str_endpoint = "WS2P V2 S 7 g1.durs.info 5.135.188.170 [2001:41d0:8:c5aa::1] 443 ws2p";
let endpoint = EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 2,
network_features: EndpointV2NetworkFeatures(vec![4u8]),
api_features: ApiFeatures(vec![7u8]),
diff --git a/lib/tools/network-documents/src/network_peer.rs b/lib/tools/network-documents/src/network_peer.rs
index 53c7cc8f8cb15b29669a88bf592f8fbd3344cf34..148498e3eb0d8deef4466ca2dae38bd1878dc9ce 100644
--- a/lib/tools/network-documents/src/network_peer.rs
+++ b/lib/tools/network-documents/src/network_peer.rs
@@ -272,7 +272,7 @@ mod tests {
fn create_endpoint_v2() -> EndpointV2 {
EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 2,
network_features: EndpointV2NetworkFeatures(vec![1u8]),
api_features: ApiFeatures(vec![7u8]),
@@ -285,7 +285,7 @@ mod tests {
}
fn create_second_endpoint_v2() -> EndpointV2 {
EndpointV2 {
- api: NetworkEndpointApi(String::from("WS2P")),
+ api: ApiName(String::from("WS2P")),
api_version: 2,
network_features: EndpointV2NetworkFeatures(vec![1u8]),
api_features: ApiFeatures(vec![7u8]),