use std::ops;
use rpki::uri;
use crate::commons::api::{Base64, HexEncodedHash};
use crate::commons::util::file::CurrentFile;
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum PublishRequest {
List,
Delta(PublishDelta),
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct PublishDelta {
publishes: Vec<Publish>,
updates: Vec<Update>,
withdraws: Vec<Withdraw>,
}
impl PublishDelta {
pub fn new(publishes: Vec<Publish>, updates: Vec<Update>, withdraws: Vec<Withdraw>) -> Self {
PublishDelta {
publishes,
updates,
withdraws,
}
}
pub fn empty() -> Self {
Self::default()
}
pub fn publishes(&self) -> &Vec<Publish> {
&self.publishes
}
pub fn updates(&self) -> &Vec<Update> {
&self.updates
}
pub fn withdraws(&self) -> &Vec<Withdraw> {
&self.withdraws
}
pub fn len(&self) -> usize {
self.publishes.len() + self.updates.len() + self.withdraws.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn unwrap(self) -> (Vec<Publish>, Vec<Update>, Vec<Withdraw>) {
(self.publishes, self.updates, self.withdraws)
}
}
impl Default for PublishDelta {
fn default() -> Self {
PublishDelta {
publishes: vec![],
updates: vec![],
withdraws: vec![],
}
}
}
impl ops::Add for PublishDelta {
type Output = PublishDelta;
fn add(mut self, mut other: Self) -> Self::Output {
self.publishes.append(&mut other.publishes);
self.updates.append(&mut other.updates);
self.withdraws.append(&mut other.withdraws);
self
}
}
#[derive(Default)]
pub struct PublishDeltaBuilder {
publishes: Vec<Publish>,
updates: Vec<Update>,
withdraws: Vec<Withdraw>,
}
impl PublishDeltaBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn add_publish(&mut self, publish: Publish) {
self.publishes.push(publish);
}
pub fn add_update(&mut self, update: Update) {
self.updates.push(update);
}
pub fn add_withdraw(&mut self, withdraw: Withdraw) {
self.withdraws.push(withdraw);
}
pub fn finish(self) -> PublishDelta {
PublishDelta {
publishes: self.publishes,
updates: self.updates,
withdraws: self.withdraws,
}
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Publish {
tag: Option<String>,
uri: uri::Rsync,
content: Base64,
}
impl Publish {
pub fn new(tag: Option<String>, uri: uri::Rsync, content: Base64) -> Self {
Publish { tag, uri, content }
}
pub fn with_hash_tag(uri: uri::Rsync, content: Base64) -> Self {
let tag = Some(content.to_hex_hash());
Publish { tag, uri, content }
}
pub fn tag(&self) -> &Option<String> {
&self.tag
}
pub fn tag_for_xml(&self) -> String {
match &self.tag {
None => "".to_string(),
Some(t) => t.clone(),
}
}
pub fn uri(&self) -> &uri::Rsync {
&self.uri
}
pub fn content(&self) -> &Base64 {
&self.content
}
pub fn unpack(self) -> (Option<String>, uri::Rsync, Base64) {
(self.tag, self.uri, self.content)
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Update {
tag: Option<String>,
uri: uri::Rsync,
content: Base64,
hash: HexEncodedHash,
}
impl Update {
pub fn new(
tag: Option<String>,
uri: uri::Rsync,
content: Base64,
old_hash: HexEncodedHash,
) -> Self {
Update {
tag,
uri,
content,
hash: old_hash,
}
}
pub fn with_hash_tag(uri: uri::Rsync, content: Base64, old_hash: HexEncodedHash) -> Self {
let tag = Some(content.to_hex_hash());
Update {
tag,
uri,
content,
hash: old_hash,
}
}
pub fn tag(&self) -> &Option<String> {
&self.tag
}
pub fn tag_for_xml(&self) -> String {
match &self.tag {
Some(t) => t.clone(),
None => "".to_string(),
}
}
pub fn uri(&self) -> &uri::Rsync {
&self.uri
}
pub fn content(&self) -> &Base64 {
&self.content
}
pub fn hash(&self) -> &HexEncodedHash {
&self.hash
}
pub fn unwrap(self) -> (Option<String>, uri::Rsync, Base64, HexEncodedHash) {
(self.tag, self.uri, self.content, self.hash)
}
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct Withdraw {
tag: Option<String>,
uri: uri::Rsync,
hash: HexEncodedHash,
}
impl Withdraw {
pub fn new(tag: Option<String>, uri: uri::Rsync, hash: HexEncodedHash) -> Self {
Withdraw { tag, uri, hash }
}
pub fn with_hash_tag(uri: uri::Rsync, hash: HexEncodedHash) -> Self {
let tag = Some(hash.to_string());
Withdraw { tag, uri, hash }
}
pub fn from_list_element(el: &ListElement) -> Self {
Withdraw {
tag: None,
uri: el.uri().clone(),
hash: el.hash().clone(),
}
}
pub fn tag(&self) -> &Option<String> {
&self.tag
}
pub fn tag_for_xml(&self) -> String {
match &self.tag {
Some(t) => t.clone(),
None => "".to_string(),
}
}
pub fn uri(&self) -> &uri::Rsync {
&self.uri
}
pub fn hash(&self) -> &HexEncodedHash {
&self.hash
}
pub fn unwrap(self) -> (Option<String>, uri::Rsync, HexEncodedHash) {
(self.tag, self.uri, self.hash)
}
}
pub enum PublishReply {
Success,
List(ListReply),
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ListReply {
elements: Vec<ListElement>,
}
impl ListReply {
pub fn new(elements: Vec<ListElement>) -> Self {
ListReply { elements }
}
pub fn from_files(files: Vec<CurrentFile>) -> Self {
let elements = files
.into_iter()
.map(CurrentFile::into_list_element)
.collect();
ListReply { elements }
}
pub fn elements(&self) -> &Vec<ListElement> {
&self.elements
}
pub fn into_elements(self) -> Vec<ListElement> {
self.elements
}
pub fn into_withdraw_delta(self) -> PublishDelta {
let withdraws: Vec<Withdraw> = self
.elements
.into_iter()
.map(|el| {
let (uri, hash) = el.unpack();
Withdraw::new(None, uri, hash)
})
.collect();
PublishDelta::new(vec![], vec![], withdraws)
}
}
#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub struct ListElement {
uri: uri::Rsync,
hash: HexEncodedHash,
}
impl ListElement {
pub fn new(uri: uri::Rsync, hash: HexEncodedHash) -> Self {
ListElement { uri, hash }
}
pub fn uri(&self) -> &uri::Rsync {
&self.uri
}
pub fn hash(&self) -> &HexEncodedHash {
&self.hash
}
pub fn unpack(self) -> (uri::Rsync, HexEncodedHash) {
(self.uri, self.hash)
}
}