use abi_stable::std_types::{ROption, RString, RVec};
use abi_stable::StableAbi;
use tarantool::session::UserId;
use tarantool::space::{SpaceId, UpdateOps};
use tarantool::tuple::{ToTupleBuffer, Tuple};
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum DmlInner {
Insert {
table: SpaceId,
tuple: RVec<u8>,
initiator: UserId,
},
Replace {
table: SpaceId,
tuple: RVec<u8>,
initiator: UserId,
},
Update {
table: SpaceId,
key: RVec<u8>,
ops: RVec<RVec<u8>>,
initiator: UserId,
},
Delete {
table: SpaceId,
key: RVec<u8>,
initiator: UserId,
},
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Dml(
pub DmlInner,
);
impl Dml {
pub fn insert(space_id: SpaceId, tuple: Tuple, initiator: UserId) -> Self {
Dml(DmlInner::Insert {
table: space_id,
tuple: RVec::from(tuple.to_vec()),
initiator,
})
}
pub fn replace(space_id: SpaceId, tuple: Tuple, initiator: UserId) -> Self {
Dml(DmlInner::Replace {
table: space_id,
tuple: RVec::from(tuple.to_vec()),
initiator,
})
}
pub fn update(
space_id: SpaceId,
key: &impl ToTupleBuffer,
ops: UpdateOps,
initiator: UserId,
) -> tarantool::Result<Self> {
let tb = key.to_tuple_buffer()?;
let raw_key = Vec::from(tb);
let ops: RVec<_> = ops
.into_inner()
.into_iter()
.map(|tb| RVec::from(Vec::from(tb)))
.collect();
Ok(Dml(DmlInner::Update {
table: space_id,
key: RVec::from(raw_key),
ops,
initiator,
}))
}
pub fn delete(
space_id: SpaceId,
key: &impl ToTupleBuffer,
initiator: UserId,
) -> tarantool::Result<Self> {
let tb = key.to_tuple_buffer()?;
let raw_key = Vec::from(tb);
Ok(Dml(DmlInner::Delete {
table: space_id,
key: RVec::from(raw_key),
initiator,
}))
}
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum OpInner {
Nop,
Dml(Dml),
BatchDml(RVec<Dml>),
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Op(
pub OpInner,
);
impl Op {
pub fn nop() -> Self {
Self(OpInner::Nop)
}
pub fn dml(dml: Dml) -> Self {
Self(OpInner::Dml(dml))
}
pub fn dml_batch(batch: Vec<Dml>) -> Self {
Self(OpInner::BatchDml(RVec::from(batch)))
}
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Bound {
pub is_included: bool,
pub key: RVec<u8>,
}
impl Bound {
pub fn new(is_included: bool, key: &impl ToTupleBuffer) -> tarantool::Result<Self> {
let tb = key.to_tuple_buffer()?;
let raw_key = Vec::from(tb);
Ok(Self {
is_included,
key: RVec::from(raw_key),
})
}
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Range {
pub table: SpaceId,
pub key_min: Bound,
pub key_max: Bound,
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct Predicate {
pub index: u64,
pub term: u64,
pub ranges: RVec<Range>,
}
impl Predicate {
pub fn new(index: u64, term: u64, ranges: Vec<Range>) -> Self {
Self {
index,
term,
ranges: RVec::from(ranges),
}
}
}
::tarantool::define_str_enum! {
#[derive(Default, StableAbi)]
#[repr(C)]
pub enum StateVariant {
#[default]
Offline = "Offline",
Online = "Online",
Expelled = "Expelled",
}
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct State {
variant: StateVariant,
incarnation: u64,
}
impl State {
pub fn new(variant: StateVariant, incarnation: u64) -> Self {
Self {
variant,
incarnation,
}
}
pub fn name(&self) -> StateVariant {
self.variant
}
pub fn incarnation(&self) -> u64 {
self.incarnation
}
}
#[derive(StableAbi, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct InstanceInfo {
raft_id: u64,
advertise_address: RString,
name: RString,
uuid: RString,
replicaset_name: RString,
replicaset_uuid: RString,
cluster_name: RString,
current_state: State,
target_state: State,
tier: RString,
}
impl InstanceInfo {
#[allow(clippy::too_many_arguments)]
pub fn new(
raft_id: u64,
advertise_address: String,
name: String,
instance_uuid: String,
replicaset_name: String,
replicaset_uuid: String,
cluster_name: String,
current_state: State,
target_state: State,
tier: String,
) -> Self {
Self {
raft_id,
advertise_address: RString::from(advertise_address),
name: RString::from(name),
uuid: RString::from(instance_uuid),
replicaset_name: RString::from(replicaset_name),
replicaset_uuid: RString::from(replicaset_uuid),
cluster_name: RString::from(cluster_name),
current_state,
target_state,
tier: RString::from(tier),
}
}
pub fn raft_id(&self) -> u64 {
self.raft_id
}
pub fn advertise_address(&self) -> &str {
self.advertise_address.as_str()
}
pub fn name(&self) -> &str {
self.name.as_str()
}
pub fn uuid(&self) -> &str {
self.uuid.as_str()
}
pub fn replicaset_name(&self) -> &str {
self.replicaset_name.as_str()
}
pub fn replicaset_uuid(&self) -> &str {
self.replicaset_uuid.as_str()
}
pub fn cluster_name(&self) -> &str {
self.cluster_name.as_str()
}
pub fn current_state(&self) -> &State {
&self.current_state
}
pub fn target_state(&self) -> &State {
&self.target_state
}
pub fn tier(&self) -> &str {
self.tier.as_str()
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(C)]
pub struct RaftInfo {
id: u64,
term: u64,
applied: u64,
leader_id: u64,
state: RaftState,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum RaftState {
Follower,
Candidate,
Leader,
PreCandidate,
}
impl RaftInfo {
pub fn new(id: u64, term: u64, applied: u64, leader_id: u64, state: RaftState) -> Self {
Self {
id,
term,
applied,
leader_id,
state,
}
}
pub fn id(&self) -> u64 {
self.id
}
pub fn term(&self) -> u64 {
self.term
}
pub fn applied(&self) -> u64 {
self.applied
}
pub fn leader_id(&self) -> u64 {
self.leader_id
}
pub fn state(&self) -> RaftState {
self.state
}
}
#[derive(StableAbi, Clone, Debug)]
#[repr(C)]
pub struct FfiListenerConfig {
pub listen: RString,
pub advertise: RString,
pub tls: ROption<FfiListenerTlsConfig>,
}
#[derive(StableAbi, Clone, Debug)]
#[repr(C)]
pub struct FfiListenerTlsConfig {
pub cert_chain_pem: RVec<u8>,
pub key_pem: RVec<u8>,
pub mtls_ca_chain_pem: ROption<RVec<u8>>,
}
#[derive(StableAbi, Clone, Debug)]
#[repr(u8)]
pub enum FfiListenerConfigError {
Undefined,
Disabled,
Malformed,
}