use std::convert::TryFrom;
use std::io::Write;
use diesel::{
backend::Backend,
deserialize::{self, FromSql},
expression::{helper_types::AsExprOf, AsExpression},
serialize::{self, Output, ToSql},
sql_types::SmallInt,
};
use crate::admin::service::messages::{self, CreateCircuit};
use crate::admin::store::diesel::schema::{
admin_event_circuit_proposal, admin_event_proposed_circuit, admin_event_proposed_node,
admin_event_proposed_node_endpoint, admin_event_proposed_service,
admin_event_proposed_service_argument, admin_event_vote_record, admin_service_event,
};
use crate::admin::store::diesel::schema::{
circuit, circuit_member, circuit_proposal, node_endpoint, proposed_circuit, proposed_node,
proposed_node_endpoint, proposed_service, proposed_service_argument, service, service_argument,
vote_record,
};
use crate::admin::store::error::AdminServiceStoreError;
use crate::admin::store::{AdminServiceEvent, AdminServiceEventBuilder, EventType};
use crate::admin::store::{
AuthorizationType, CircuitStatus, DurabilityType, PersistenceType, ProposalType, RouteType,
Vote, VoteRecord, VoteRecordBuilder,
};
use crate::admin::store::{Circuit, CircuitProposal, ProposedCircuit};
use crate::error::{InternalError, InvalidStateError};
use crate::public_key::PublicKey;
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "circuit_proposal"]
#[primary_key(circuit_id)]
pub struct CircuitProposalModel {
pub proposal_type: String,
pub circuit_id: String,
pub circuit_hash: String,
pub requester: Vec<u8>,
pub requester_node_id: String,
}
impl From<&CircuitProposal> for CircuitProposalModel {
fn from(proposal: &CircuitProposal) -> Self {
CircuitProposalModel {
proposal_type: String::from(proposal.proposal_type()),
circuit_id: proposal.circuit_id().into(),
circuit_hash: proposal.circuit_hash().into(),
requester: proposal.requester().as_slice().to_vec(),
requester_node_id: proposal.requester_node_id().into(),
}
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "proposed_circuit"]
#[belongs_to(CircuitProposalModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id)]
pub struct ProposedCircuitModel {
pub circuit_id: String,
pub authorization_type: String,
pub persistence: String,
pub durability: String,
pub routes: String,
pub circuit_management_type: String,
pub application_metadata: Option<Vec<u8>>,
pub comments: Option<String>,
pub display_name: Option<String>,
pub circuit_version: i32,
pub circuit_status: CircuitStatusModel,
}
impl From<&ProposedCircuit> for ProposedCircuitModel {
fn from(proposed_circuit: &ProposedCircuit) -> Self {
ProposedCircuitModel {
circuit_id: proposed_circuit.circuit_id().into(),
authorization_type: String::from(proposed_circuit.authorization_type()),
persistence: String::from(proposed_circuit.persistence()),
durability: String::from(proposed_circuit.durability()),
routes: String::from(proposed_circuit.routes()),
circuit_management_type: proposed_circuit.circuit_management_type().into(),
application_metadata: proposed_circuit.application_metadata().clone(),
comments: proposed_circuit.comments().clone(),
display_name: proposed_circuit.display_name().clone(),
circuit_version: proposed_circuit.circuit_version(),
circuit_status: CircuitStatusModel::from(proposed_circuit.circuit_status()),
}
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "vote_record"]
#[belongs_to(CircuitProposalModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, voter_node_id)]
pub struct VoteRecordModel {
pub circuit_id: String,
pub public_key: Vec<u8>,
pub vote: String,
pub voter_node_id: String,
pub position: i32,
}
impl TryFrom<&CircuitProposal> for Vec<VoteRecordModel> {
type Error = AdminServiceStoreError;
fn try_from(proposal: &CircuitProposal) -> Result<Self, Self::Error> {
proposal
.votes()
.iter()
.enumerate()
.map(|(idx, vote)| {
Ok(VoteRecordModel {
circuit_id: proposal.circuit_id().into(),
public_key: vote.public_key().as_slice().to_vec(),
vote: String::from(vote.vote()),
voter_node_id: vote.voter_node_id().into(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect::<Result<Vec<VoteRecordModel>, AdminServiceStoreError>>()
}
}
impl TryFrom<&VoteRecordModel> for VoteRecord {
type Error = AdminServiceStoreError;
fn try_from(vote: &VoteRecordModel) -> Result<Self, Self::Error> {
VoteRecordBuilder::new()
.with_public_key(&PublicKey::from_bytes(vote.public_key.to_vec()))
.with_vote(&Vote::try_from(vote.vote.clone())?)
.with_voter_node_id(&vote.voter_node_id)
.build()
.map_err(AdminServiceStoreError::InvalidStateError)
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "proposed_node"]
#[belongs_to(ProposedCircuitModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, node_id)]
pub struct ProposedNodeModel {
pub circuit_id: String,
pub node_id: String,
pub position: i32,
pub public_key: Option<Vec<u8>>,
}
impl TryFrom<&ProposedCircuit> for Vec<ProposedNodeModel> {
type Error = AdminServiceStoreError;
fn try_from(proposed_circuit: &ProposedCircuit) -> Result<Self, Self::Error> {
proposed_circuit
.members()
.iter()
.enumerate()
.map(|(idx, node)| {
Ok(ProposedNodeModel {
circuit_id: proposed_circuit.circuit_id().into(),
node_id: node.node_id().into(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
public_key: node
.public_key()
.clone()
.map(|public_key| public_key.into_bytes()),
})
})
.collect::<Result<Vec<ProposedNodeModel>, AdminServiceStoreError>>()
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "proposed_node_endpoint"]
#[belongs_to(ProposedCircuitModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, node_id, endpoint)]
pub struct ProposedNodeEndpointModel {
pub node_id: String,
pub circuit_id: String,
pub endpoint: String,
pub position: i32,
}
impl TryFrom<&ProposedCircuit> for Vec<ProposedNodeEndpointModel> {
type Error = AdminServiceStoreError;
fn try_from(proposed_circuit: &ProposedCircuit) -> Result<Self, Self::Error> {
let mut endpoint_models = Vec::new();
for node in proposed_circuit.members() {
endpoint_models.extend(
node.endpoints()
.iter()
.enumerate()
.map(|(idx, endpoint)| {
Ok(ProposedNodeEndpointModel {
node_id: node.node_id().into(),
circuit_id: proposed_circuit.circuit_id().into(),
endpoint: endpoint.clone(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect::<Result<Vec<ProposedNodeEndpointModel>, AdminServiceStoreError>>()?,
);
}
Ok(endpoint_models)
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "proposed_service"]
#[belongs_to(ProposedCircuitModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, service_id)]
pub struct ProposedServiceModel {
pub circuit_id: String,
pub service_id: String,
pub service_type: String,
pub node_id: String,
pub position: i32,
}
impl TryFrom<&ProposedCircuit> for Vec<ProposedServiceModel> {
type Error = AdminServiceStoreError;
fn try_from(proposed_circuit: &ProposedCircuit) -> Result<Self, Self::Error> {
proposed_circuit
.roster()
.iter()
.enumerate()
.map(|(idx, service)| {
Ok(ProposedServiceModel {
circuit_id: proposed_circuit.circuit_id().into(),
service_id: service.service_id().into(),
service_type: service.service_type().into(),
node_id: service.node_id().into(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect::<Result<Vec<ProposedServiceModel>, AdminServiceStoreError>>()
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "proposed_service_argument"]
#[belongs_to(ProposedCircuitModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, service_id, key)]
pub struct ProposedServiceArgumentModel {
pub circuit_id: String,
pub service_id: String,
pub key: String,
pub value: String,
pub position: i32,
}
impl TryFrom<&ProposedCircuit> for Vec<ProposedServiceArgumentModel> {
type Error = AdminServiceStoreError;
fn try_from(proposed_circuit: &ProposedCircuit) -> Result<Self, Self::Error> {
let mut service_arguments = Vec::new();
for service in proposed_circuit.roster() {
service_arguments.extend(
service
.arguments()
.iter()
.enumerate()
.map(|(idx, (key, value))| {
Ok(ProposedServiceArgumentModel {
circuit_id: proposed_circuit.circuit_id().into(),
service_id: service.service_id().into(),
key: key.into(),
value: value.into(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect::<Result<Vec<ProposedServiceArgumentModel>, AdminServiceStoreError>>(
)?,
);
}
Ok(service_arguments)
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "service"]
#[belongs_to(CircuitModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, service_id)]
pub struct ServiceModel {
pub circuit_id: String,
pub service_id: String,
pub service_type: String,
pub node_id: String,
pub position: i32,
}
impl TryFrom<&Circuit> for Vec<ServiceModel> {
type Error = AdminServiceStoreError;
fn try_from(circuit: &Circuit) -> Result<Self, Self::Error> {
circuit
.roster()
.iter()
.enumerate()
.map(|(idx, service)| {
Ok(ServiceModel {
circuit_id: circuit.circuit_id().into(),
service_id: service.service_id().into(),
service_type: service.service_type().into(),
node_id: service.node_id().into(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect::<Result<Vec<ServiceModel>, AdminServiceStoreError>>()
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "service_argument"]
#[belongs_to(CircuitModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, service_id, key)]
pub struct ServiceArgumentModel {
pub circuit_id: String,
pub service_id: String,
pub key: String,
pub value: String,
pub position: i32,
}
impl TryFrom<&Circuit> for Vec<ServiceArgumentModel> {
type Error = AdminServiceStoreError;
fn try_from(circuit: &Circuit) -> Result<Self, Self::Error> {
let mut service_arguments = Vec::new();
for service in circuit.roster() {
service_arguments.extend(
service
.arguments()
.iter()
.enumerate()
.map(|(idx, (key, value))| {
Ok(ServiceArgumentModel {
circuit_id: circuit.circuit_id().into(),
service_id: service.service_id().into(),
key: key.clone(),
value: value.clone(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect::<Result<Vec<ServiceArgumentModel>, AdminServiceStoreError>>()?,
);
}
Ok(service_arguments)
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "circuit"]
#[primary_key(circuit_id)]
pub struct CircuitModel {
pub circuit_id: String,
pub authorization_type: String,
pub persistence: String,
pub durability: String,
pub routes: String,
pub circuit_management_type: String,
pub display_name: Option<String>,
pub circuit_version: i32,
pub circuit_status: CircuitStatusModel,
}
impl From<&Circuit> for CircuitModel {
fn from(circuit: &Circuit) -> Self {
CircuitModel {
circuit_id: circuit.circuit_id().into(),
authorization_type: String::from(circuit.authorization_type()),
persistence: String::from(circuit.persistence()),
durability: String::from(circuit.durability()),
routes: String::from(circuit.routes()),
circuit_management_type: circuit.circuit_management_type().into(),
display_name: circuit.display_name().clone(),
circuit_version: circuit.circuit_version(),
circuit_status: CircuitStatusModel::from(circuit.circuit_status()),
}
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "circuit_member"]
#[belongs_to(CircuitModel, foreign_key = "circuit_id")]
#[primary_key(circuit_id, node_id)]
pub struct CircuitMemberModel {
pub circuit_id: String,
pub node_id: String,
pub position: i32,
pub public_key: Option<Vec<u8>>,
}
impl TryFrom<&Circuit> for Vec<CircuitMemberModel> {
type Error = AdminServiceStoreError;
fn try_from(circuit: &Circuit) -> Result<Self, Self::Error> {
circuit
.members()
.iter()
.enumerate()
.map(|(idx, node)| {
Ok(CircuitMemberModel {
circuit_id: circuit.circuit_id().into(),
node_id: node.node_id().into(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
public_key: node
.public_key()
.clone()
.map(|public_key| public_key.into_bytes()),
})
})
.collect::<Result<Vec<CircuitMemberModel>, AdminServiceStoreError>>()
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "node_endpoint"]
#[primary_key(node_id, endpoint)]
pub struct NodeEndpointModel {
pub node_id: String,
pub endpoint: String,
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_service_event"]
#[primary_key(id)]
pub struct AdminServiceEventModel {
pub id: i64,
pub event_type: String,
pub data: Option<Vec<u8>>,
}
#[derive(AsChangeset, Insertable, PartialEq, Debug)]
#[table_name = "admin_service_event"]
pub struct NewAdminServiceEventModel<'a> {
pub event_type: &'a str,
pub data: Option<&'a [u8]>,
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_event_circuit_proposal"]
#[belongs_to(AdminServiceEventModel, foreign_key = "event_id")]
#[primary_key(event_id)]
pub struct AdminEventCircuitProposalModel {
pub event_id: i64,
pub proposal_type: String,
pub circuit_id: String,
pub circuit_hash: String,
pub requester: Vec<u8>,
pub requester_node_id: String,
}
impl From<(i64, &messages::CircuitProposal)> for AdminEventCircuitProposalModel {
fn from((event_id, proposal): (i64, &messages::CircuitProposal)) -> Self {
AdminEventCircuitProposalModel {
event_id,
proposal_type: String::from(&proposal.proposal_type),
circuit_id: proposal.circuit_id.to_string(),
circuit_hash: proposal.circuit_hash.to_string(),
requester: proposal.requester.to_vec(),
requester_node_id: proposal.requester_node_id.to_string(),
}
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_event_proposed_circuit"]
#[belongs_to(AdminServiceEventModel, foreign_key = "event_id")]
#[primary_key(event_id)]
pub struct AdminEventProposedCircuitModel {
pub event_id: i64,
pub circuit_id: String,
pub authorization_type: String,
pub persistence: String,
pub durability: String,
pub routes: String,
pub circuit_management_type: String,
pub application_metadata: Option<Vec<u8>>,
pub comments: Option<String>,
pub display_name: Option<String>,
pub circuit_version: i32,
pub circuit_status: CircuitStatusModel,
}
impl From<(i64, &CreateCircuit)> for AdminEventProposedCircuitModel {
fn from((event_id, create_circuit): (i64, &CreateCircuit)) -> Self {
let application_metadata = if create_circuit.application_metadata.is_empty() {
None
} else {
Some(create_circuit.application_metadata.to_vec())
};
AdminEventProposedCircuitModel {
event_id,
circuit_id: create_circuit.circuit_id.to_string(),
authorization_type: String::from(&create_circuit.authorization_type),
persistence: String::from(&create_circuit.persistence),
durability: String::from(&create_circuit.durability),
routes: String::from(&create_circuit.routes),
circuit_management_type: create_circuit.circuit_management_type.to_string(),
application_metadata,
comments: create_circuit.comments.clone(),
display_name: create_circuit.display_name.clone(),
circuit_version: create_circuit.circuit_version,
circuit_status: CircuitStatusModel::from(&create_circuit.circuit_status),
}
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_event_vote_record"]
#[belongs_to(AdminServiceEventModel, foreign_key = "event_id")]
#[primary_key(event_id, voter_node_id)]
pub struct AdminEventVoteRecordModel {
pub event_id: i64,
pub public_key: Vec<u8>,
pub vote: String,
pub voter_node_id: String,
pub position: i32,
}
impl AdminEventVoteRecordModel {
pub(super) fn list_from_proposal_with_id(
event_id: i64,
proposal: &messages::CircuitProposal,
) -> Result<Vec<AdminEventVoteRecordModel>, AdminServiceStoreError> {
proposal
.votes
.iter()
.enumerate()
.map(|(idx, vote)| {
Ok(AdminEventVoteRecordModel {
event_id,
public_key: vote.public_key.to_vec(),
vote: String::from(&vote.vote),
voter_node_id: vote.voter_node_id.to_string(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect()
}
}
impl TryFrom<&AdminEventVoteRecordModel> for VoteRecord {
type Error = InvalidStateError;
fn try_from(
admin_event_vote_record_model: &AdminEventVoteRecordModel,
) -> Result<Self, Self::Error> {
VoteRecordBuilder::new()
.with_public_key(&PublicKey::from_bytes(
admin_event_vote_record_model.public_key.to_vec(),
))
.with_vote(
&Vote::try_from(admin_event_vote_record_model.vote.clone()).map_err(|_| {
InvalidStateError::with_message("Unable to convert string to Vote".into())
})?,
)
.with_voter_node_id(&admin_event_vote_record_model.voter_node_id)
.build()
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_event_proposed_node"]
#[belongs_to(AdminServiceEventModel, foreign_key = "event_id")]
#[primary_key(event_id, node_id)]
pub struct AdminEventProposedNodeModel {
pub event_id: i64,
pub node_id: String,
pub position: i32,
}
impl AdminEventProposedNodeModel {
pub(super) fn list_from_proposal_with_id(
event_id: i64,
proposal: &messages::CircuitProposal,
) -> Result<Vec<AdminEventProposedNodeModel>, AdminServiceStoreError> {
proposal
.circuit
.members
.iter()
.enumerate()
.map(|(idx, node)| {
Ok(AdminEventProposedNodeModel {
event_id,
node_id: node.node_id.to_string(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect()
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_event_proposed_node_endpoint"]
#[belongs_to(AdminServiceEventModel, foreign_key = "event_id")]
#[primary_key(event_id, node_id, endpoint)]
pub struct AdminEventProposedNodeEndpointModel {
pub event_id: i64,
pub node_id: String,
pub endpoint: String,
pub position: i32,
}
impl AdminEventProposedNodeEndpointModel {
pub(super) fn list_from_proposal_with_id(
event_id: i64,
proposal: &messages::CircuitProposal,
) -> Result<Vec<AdminEventProposedNodeEndpointModel>, AdminServiceStoreError> {
let mut endpoint_models = Vec::new();
for node in &proposal.circuit.members {
endpoint_models.extend(
node.endpoints
.iter()
.enumerate()
.map(|(idx, endpoint)| Ok(AdminEventProposedNodeEndpointModel {
event_id,
node_id: node.node_id.to_string(),
endpoint: endpoint.to_string(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
}))
.collect::<Result<
Vec<AdminEventProposedNodeEndpointModel>, AdminServiceStoreError>
>()?,
);
}
Ok(endpoint_models)
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_event_proposed_service"]
#[belongs_to(AdminServiceEventModel, foreign_key = "event_id")]
#[primary_key(event_id, service_id)]
pub struct AdminEventProposedServiceModel {
pub event_id: i64,
pub service_id: String,
pub service_type: String,
pub node_id: String,
pub position: i32,
}
impl AdminEventProposedServiceModel {
pub(super) fn list_from_proposal_with_id(
event_id: i64,
proposal: &messages::CircuitProposal,
) -> Result<Vec<AdminEventProposedServiceModel>, AdminServiceStoreError> {
proposal
.circuit
.roster
.iter()
.enumerate()
.map(|(idx, service)| {
Ok(AdminEventProposedServiceModel {
event_id,
service_id: service.service_id.to_string(),
service_type: service.service_type.to_string(),
node_id: service
.allowed_nodes
.get(0)
.ok_or_else(|| {
AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message(
"Must contain 1 node ID".to_string(),
),
)
})?
.to_string(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(InternalError::with_message(
"Unable to convert index into i32".to_string(),
))
})?,
})
})
.collect::<Result<Vec<AdminEventProposedServiceModel>, AdminServiceStoreError>>()
}
}
#[derive(Debug, PartialEq, Associations, Identifiable, Insertable, Queryable, QueryableByName)]
#[table_name = "admin_event_proposed_service_argument"]
#[belongs_to(AdminServiceEventModel, foreign_key = "event_id")]
#[primary_key(event_id, service_id, key)]
pub struct AdminEventProposedServiceArgumentModel {
pub event_id: i64,
pub service_id: String,
pub key: String,
pub value: String,
pub position: i32,
}
impl AdminEventProposedServiceArgumentModel {
pub(super) fn list_from_proposal_with_id(
event_id: i64,
proposal: &messages::CircuitProposal,
) -> Result<Vec<AdminEventProposedServiceArgumentModel>, AdminServiceStoreError> {
let mut service_arguments = Vec::new();
for service in &proposal.circuit.roster {
service_arguments.extend(
service
.arguments
.iter()
.enumerate()
.map(|(idx, (key, value))| {
Ok(AdminEventProposedServiceArgumentModel {
event_id,
service_id: service.service_id.to_string(),
key: key.into(),
value: value.into(),
position: i32::try_from(idx).map_err(|_| {
AdminServiceStoreError::InternalError(
InternalError::with_message(
"Unable to convert index into i32".to_string(),
),
)
})?,
})
})
.collect::<Result<
Vec<AdminEventProposedServiceArgumentModel>,
AdminServiceStoreError,
>>()?,
);
}
Ok(service_arguments)
}
}
impl<'a> From<&'a messages::AdminServiceEvent> for NewAdminServiceEventModel<'a> {
fn from(event: &'a messages::AdminServiceEvent) -> Self {
match event {
messages::AdminServiceEvent::ProposalSubmitted(_) => NewAdminServiceEventModel {
event_type: "ProposalSubmitted",
data: None,
},
messages::AdminServiceEvent::ProposalVote((_, data)) => NewAdminServiceEventModel {
event_type: "ProposalVote",
data: Some(data),
},
messages::AdminServiceEvent::ProposalAccepted((_, data)) => NewAdminServiceEventModel {
event_type: "ProposalAccepted",
data: Some(data),
},
messages::AdminServiceEvent::ProposalRejected((_, data)) => NewAdminServiceEventModel {
event_type: "ProposalRejected",
data: Some(data),
},
messages::AdminServiceEvent::CircuitReady(_) => NewAdminServiceEventModel {
event_type: "CircuitReady",
data: None,
},
messages::AdminServiceEvent::CircuitDisbanded(_) => NewAdminServiceEventModel {
event_type: "CircuitDisbanded",
data: None,
},
}
}
}
impl TryFrom<(AdminServiceEventModel, CircuitProposal)> for AdminServiceEvent {
type Error = AdminServiceStoreError;
fn try_from(
(event_model, proposal): (AdminServiceEventModel, CircuitProposal),
) -> Result<Self, Self::Error> {
match (event_model.event_type.as_ref(), event_model.data) {
("ProposalSubmitted", None) => AdminServiceEventBuilder::new()
.with_event_id(event_model.id)
.with_event_type(&EventType::ProposalSubmitted)
.with_proposal(&proposal)
.build()
.map_err(AdminServiceStoreError::InvalidStateError),
("ProposalVote", Some(requester)) => AdminServiceEventBuilder::new()
.with_event_id(event_model.id)
.with_event_type(&EventType::ProposalVote { requester })
.with_proposal(&proposal)
.build()
.map_err(AdminServiceStoreError::InvalidStateError),
("ProposalAccepted", Some(requester)) => AdminServiceEventBuilder::new()
.with_event_id(event_model.id)
.with_event_type(&EventType::ProposalAccepted { requester })
.with_proposal(&proposal)
.build()
.map_err(AdminServiceStoreError::InvalidStateError),
("ProposalRejected", Some(requester)) => AdminServiceEventBuilder::new()
.with_event_id(event_model.id)
.with_event_type(&EventType::ProposalRejected { requester })
.with_proposal(&proposal)
.build()
.map_err(AdminServiceStoreError::InvalidStateError),
("CircuitReady", None) => AdminServiceEventBuilder::new()
.with_event_id(event_model.id)
.with_event_type(&EventType::CircuitReady)
.with_proposal(&proposal)
.build()
.map_err(AdminServiceStoreError::InvalidStateError),
("CircuitDisbanded", None) => AdminServiceEventBuilder::new()
.with_event_id(event_model.id)
.with_event_type(&EventType::CircuitDisbanded)
.with_proposal(&proposal)
.build()
.map_err(AdminServiceStoreError::InvalidStateError),
_ => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message(
"Unable to convert AdminServiceEventModel to AdminServiceEvent".into(),
),
)),
}
}
}
impl TryFrom<String> for Vote {
type Error = AdminServiceStoreError;
fn try_from(variant: String) -> Result<Self, Self::Error> {
match variant.as_ref() {
"Accept" => Ok(Vote::Accept),
"Reject" => Ok(Vote::Reject),
_ => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message("Unable to convert string to Vote".into()),
)),
}
}
}
impl From<&Vote> for String {
fn from(variant: &Vote) -> Self {
match variant {
Vote::Accept => String::from("Accept"),
Vote::Reject => String::from("Reject"),
}
}
}
impl From<&messages::Vote> for String {
fn from(variant: &messages::Vote) -> Self {
match variant {
messages::Vote::Accept => String::from("Accept"),
messages::Vote::Reject => String::from("Reject"),
}
}
}
impl TryFrom<String> for ProposalType {
type Error = AdminServiceStoreError;
fn try_from(variant: String) -> Result<Self, Self::Error> {
match variant.as_ref() {
"Create" => Ok(ProposalType::Create),
"UpdateRoster" => Ok(ProposalType::UpdateRoster),
"AddNode" => Ok(ProposalType::AddNode),
"RemoveNode" => Ok(ProposalType::RemoveNode),
"Disband" => Ok(ProposalType::Disband),
_ => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message("Unable to convert string to ProposalType".into()),
)),
}
}
}
impl From<&ProposalType> for String {
fn from(variant: &ProposalType) -> Self {
match variant {
ProposalType::Create => String::from("Create"),
ProposalType::UpdateRoster => String::from("UpdateRoster"),
ProposalType::AddNode => String::from("AddNode"),
ProposalType::RemoveNode => String::from("RemoveNode"),
ProposalType::Disband => String::from("Disband"),
}
}
}
impl From<&messages::ProposalType> for String {
fn from(variant: &messages::ProposalType) -> Self {
match variant {
messages::ProposalType::Create => String::from("Create"),
messages::ProposalType::UpdateRoster => String::from("UpdateRoster"),
messages::ProposalType::AddNode => String::from("AddNode"),
messages::ProposalType::RemoveNode => String::from("RemoveNode"),
messages::ProposalType::Disband => String::from("Disband"),
}
}
}
impl TryFrom<String> for AuthorizationType {
type Error = AdminServiceStoreError;
fn try_from(variant: String) -> Result<Self, Self::Error> {
match variant.as_ref() {
"Trust" => Ok(AuthorizationType::Trust),
"Challenge" => Ok(AuthorizationType::Challenge),
_ => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message(
"Unable to convert string to AuthorizationType".into(),
),
)),
}
}
}
impl From<&AuthorizationType> for String {
fn from(variant: &AuthorizationType) -> Self {
match variant {
AuthorizationType::Trust => String::from("Trust"),
AuthorizationType::Challenge => String::from("Challenge"),
}
}
}
impl From<&messages::AuthorizationType> for String {
fn from(variant: &messages::AuthorizationType) -> Self {
match variant {
messages::AuthorizationType::Trust => String::from("Trust"),
messages::AuthorizationType::Challenge => String::from("Challenge"),
}
}
}
impl TryFrom<String> for PersistenceType {
type Error = AdminServiceStoreError;
fn try_from(variant: String) -> Result<Self, Self::Error> {
match variant.as_ref() {
"Any" => Ok(PersistenceType::Any),
_ => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message(
"Unable to convert string to PersistenceType".into(),
),
)),
}
}
}
impl From<&PersistenceType> for String {
fn from(variant: &PersistenceType) -> Self {
match variant {
PersistenceType::Any => String::from("Any"),
}
}
}
impl From<&messages::PersistenceType> for String {
fn from(variant: &messages::PersistenceType) -> Self {
match variant {
messages::PersistenceType::Any => String::from("Any"),
}
}
}
impl TryFrom<String> for DurabilityType {
type Error = AdminServiceStoreError;
fn try_from(variant: String) -> Result<Self, Self::Error> {
match variant.as_ref() {
"NoDurability" => Ok(DurabilityType::NoDurability),
_ => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message(
"Unable to convert string to DurabilityType".into(),
),
)),
}
}
}
impl From<&DurabilityType> for String {
fn from(variant: &DurabilityType) -> Self {
match variant {
DurabilityType::NoDurability => String::from("NoDurability"),
}
}
}
impl From<&messages::DurabilityType> for String {
fn from(variant: &messages::DurabilityType) -> Self {
match variant {
messages::DurabilityType::NoDurability => String::from("NoDurability"),
}
}
}
impl TryFrom<String> for RouteType {
type Error = AdminServiceStoreError;
fn try_from(variant: String) -> Result<Self, Self::Error> {
match variant.as_ref() {
"Any" => Ok(RouteType::Any),
_ => Err(AdminServiceStoreError::InvalidStateError(
InvalidStateError::with_message("Unable to convert string to RouteType".into()),
)),
}
}
}
impl From<&RouteType> for String {
fn from(variant: &RouteType) -> Self {
match variant {
RouteType::Any => String::from("Any"),
}
}
}
impl From<&messages::RouteType> for String {
fn from(variant: &messages::RouteType) -> Self {
match variant {
messages::RouteType::Any => String::from("Any"),
}
}
}
#[repr(i16)]
#[derive(Debug, Copy, Clone, PartialEq, FromSqlRow)]
pub enum CircuitStatusModel {
Active = 1,
Disbanded = 2,
Abandoned = 3,
}
impl From<&CircuitStatus> for CircuitStatusModel {
fn from(store_status: &CircuitStatus) -> Self {
match *store_status {
CircuitStatus::Active => CircuitStatusModel::Active,
CircuitStatus::Disbanded => CircuitStatusModel::Disbanded,
CircuitStatus::Abandoned => CircuitStatusModel::Abandoned,
}
}
}
impl From<&messages::CircuitStatus> for CircuitStatusModel {
fn from(messages_status: &messages::CircuitStatus) -> Self {
match *messages_status {
messages::CircuitStatus::Active => CircuitStatusModel::Active,
messages::CircuitStatus::Disbanded => CircuitStatusModel::Disbanded,
messages::CircuitStatus::Abandoned => CircuitStatusModel::Abandoned,
}
}
}
impl From<&CircuitStatusModel> for CircuitStatus {
fn from(status_model: &CircuitStatusModel) -> Self {
match *status_model {
CircuitStatusModel::Active => CircuitStatus::Active,
CircuitStatusModel::Disbanded => CircuitStatus::Disbanded,
CircuitStatusModel::Abandoned => CircuitStatus::Abandoned,
}
}
}
impl From<&CircuitStatusModel> for messages::CircuitStatus {
fn from(status_model: &CircuitStatusModel) -> Self {
match *status_model {
CircuitStatusModel::Active => messages::CircuitStatus::Active,
CircuitStatusModel::Disbanded => messages::CircuitStatus::Disbanded,
CircuitStatusModel::Abandoned => messages::CircuitStatus::Abandoned,
}
}
}
impl<DB> ToSql<SmallInt, DB> for CircuitStatusModel
where
DB: Backend,
i16: ToSql<SmallInt, DB>,
{
fn to_sql<W: Write>(&self, out: &mut Output<W, DB>) -> serialize::Result {
(*self as i16).to_sql(out)
}
}
impl AsExpression<SmallInt> for CircuitStatusModel {
type Expression = AsExprOf<i16, SmallInt>;
fn as_expression(self) -> Self::Expression {
<i16 as AsExpression<SmallInt>>::as_expression(self as i16)
}
}
impl<'a> AsExpression<SmallInt> for &'a CircuitStatusModel {
type Expression = AsExprOf<i16, SmallInt>;
fn as_expression(self) -> Self::Expression {
<i16 as AsExpression<SmallInt>>::as_expression((*self) as i16)
}
}
impl<DB> FromSql<SmallInt, DB> for CircuitStatusModel
where
DB: Backend,
i16: FromSql<SmallInt, DB>,
{
fn from_sql(bytes: Option<&DB::RawValue>) -> deserialize::Result<Self> {
match i16::from_sql(bytes)? {
1 => Ok(CircuitStatusModel::Active),
2 => Ok(CircuitStatusModel::Disbanded),
3 => Ok(CircuitStatusModel::Abandoned),
int => Err(format!("Invalid circuit status {}", int).into()),
}
}
}