177 lines
4.8 KiB
Markdown
177 lines
4.8 KiB
Markdown
ICANN RDAP Common
|
||
=================
|
||
|
||
This is a common component library for the Registration Data Access Protocol (RDAP) written and sponsored
|
||
by the Internet Corporation for Assigned Names and Numbers [(ICANN)](https://www.icann.org).
|
||
RDAP is standard of the [IETF](https://ietf.org/), and extensions
|
||
to RDAP are a current work activity of the IETF's [REGEXT working group](https://datatracker.ietf.org/wg/regext/documents/).
|
||
More information on ICANN's role in RDAP can be found [here](https://www.icann.org/rdap).
|
||
General information on RDAP can be found [here](https://rdap.rcode3.com/).
|
||
|
||
|
||
Installation
|
||
------------
|
||
|
||
Add the library to your Cargo.toml: `cargo add icann-rdap-common`.
|
||
|
||
This library can be compiled for WASM targets.
|
||
|
||
Usage
|
||
-----
|
||
|
||
Create some RDAP objects:
|
||
|
||
```rust
|
||
// create an entity
|
||
use icann_rdap_common::response::Entity;
|
||
let holder = Entity::builder().handle("foo-BAR").build();
|
||
|
||
// create an RDAP domain
|
||
use icann_rdap_common::response::Domain;
|
||
let domain = Domain::builder().ldh_name("example.com").entity(holder.clone()).build();
|
||
|
||
// create an IP network
|
||
use icann_rdap_common::response::Network;
|
||
let net = Network::builder().cidr("10.0.0.0/16").entity(holder.clone()).build().unwrap();
|
||
|
||
// create a nameserver
|
||
use icann_rdap_common::response::Nameserver;
|
||
let ns = Nameserver::builder().ldh_name("ns1.example.com").entity(holder.clone()).build().unwrap();
|
||
|
||
// create an autnum
|
||
use icann_rdap_common::response::Autnum;
|
||
let autnum = Autnum::builder().autnum_range(700..700).entity(holder).build();
|
||
```
|
||
|
||
Parse RDAP JSON:
|
||
|
||
```rust
|
||
use icann_rdap_common::prelude::*;
|
||
|
||
let json = r#"
|
||
{
|
||
"objectClassName": "ip network",
|
||
"links": [
|
||
{
|
||
"value": "http://localhost:3000/rdap/ip/10.0.0.0/16",
|
||
"rel": "self",
|
||
"href": "http://localhost:3000/rdap/ip/10.0.0.0/16",
|
||
"type": "application/rdap+json"
|
||
}
|
||
],
|
||
"events": [
|
||
{
|
||
"eventAction": "registration",
|
||
"eventDate": "2023-06-16T22:56:49.594173356+00:00"
|
||
},
|
||
{
|
||
"eventAction": "last changed",
|
||
"eventDate": "2023-06-16T22:56:49.594189140+00:00"
|
||
}
|
||
],
|
||
"startAddress": "10.0.0.0",
|
||
"endAddress": "10.0.255.255",
|
||
"ipVersion": "v4"
|
||
}
|
||
"#;
|
||
|
||
let rdap: RdapResponse = serde_json::from_str(json).unwrap();
|
||
assert!(matches!(rdap, RdapResponse::Network(_)));
|
||
```
|
||
|
||
RDAP uses jCard, the JSON version of vCard, to model "contact information"
|
||
(e.g. postal addresses, phone numbers, etc...). Because jCard is difficult
|
||
to use and there might be other contact models standardized by the IETF,
|
||
this library includes the [`contact::Contact`] struct. This struct can be
|
||
converted to and from jCard/vCard with the [`contact::Contact::from_vcard`]
|
||
and [`contact::Contact::to_vcard`] functions.
|
||
|
||
[`contact::Contact`] structs can be built using the builder.
|
||
|
||
```rust
|
||
use icann_rdap_common::contact::Contact;
|
||
|
||
let contact = Contact::builder()
|
||
.kind("individual")
|
||
.full_name("Bob Smurd")
|
||
.build();
|
||
```
|
||
|
||
Once built, a Contact struct can be converted to an array of [serde_json::Value]'s,
|
||
which can be used with serde to serialize to JSON.
|
||
|
||
```rust
|
||
use icann_rdap_common::contact::Contact;
|
||
use serde::Serialize;
|
||
use serde_json::Value;
|
||
|
||
let contact = Contact::builder()
|
||
.kind("individual")
|
||
.full_name("Bob Smurd")
|
||
.build();
|
||
|
||
let v = contact.to_vcard();
|
||
let json = serde_json::to_string(&v);
|
||
```
|
||
|
||
To deserialize, use the `from_vcard` function.
|
||
|
||
```rust
|
||
use icann_rdap_common::contact::Contact;
|
||
use serde::Deserialize;
|
||
use serde_json::Value;
|
||
|
||
let json = r#"
|
||
[
|
||
"vcard",
|
||
[
|
||
["version", {}, "text", "4.0"],
|
||
["fn", {}, "text", "Joe User"],
|
||
["kind", {}, "text", "individual"],
|
||
["org", {
|
||
"type":"work"
|
||
}, "text", "Example"],
|
||
["title", {}, "text", "Research Scientist"],
|
||
["role", {}, "text", "Project Lead"],
|
||
["adr",
|
||
{ "type":"work" },
|
||
"text",
|
||
[
|
||
"",
|
||
"Suite 1234",
|
||
"4321 Rue Somewhere",
|
||
"Quebec",
|
||
"QC",
|
||
"G1V 2M2",
|
||
"Canada"
|
||
]
|
||
],
|
||
["tel",
|
||
{ "type":["work", "voice"], "pref":"1" },
|
||
"uri", "tel:+1-555-555-1234;ext=102"
|
||
],
|
||
["email",
|
||
{ "type":"work" },
|
||
"text", "joe.user@example.com"
|
||
]
|
||
]
|
||
]"#;
|
||
|
||
let data: Vec<Value> = serde_json::from_str(json).unwrap();
|
||
let contact = Contact::from_vcard(&data);
|
||
```
|
||
|
||
License
|
||
-------
|
||
|
||
Licensed under either of
|
||
* Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
|
||
* MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) at your option.
|
||
|
||
Contribution
|
||
------------
|
||
|
||
Unless you explicitly state otherwise, any contribution, as defined in the Apache-2.0 license,
|
||
intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license,
|
||
shall be dual licensed pursuant to the Apache License, Version 2.0 or the MIT License referenced
|
||
as above, at ICANN’s option, without any additional terms or conditions.
|