use std::fmt;
use display_more::DisplayOptionExt;
use openraft_macros::since;
use crate::RaftTypeConfig;
use crate::type_config::alias::LogIdOf;
use crate::type_config::alias::VoteOf;
#[since(version = "0.10.0", change = "added last_log_id")]
#[derive(Clone, Debug)]
#[derive(PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize), serde(bound = ""))]
pub struct TransferLeaderRequest<C>
where C: RaftTypeConfig
{
pub(crate) from_leader: VoteOf<C>,
pub(crate) to_node_id: C::NodeId,
pub(crate) last_log_id: Option<LogIdOf<C>>,
}
impl<C> TransferLeaderRequest<C>
where C: RaftTypeConfig
{
#[since(version = "0.10.0", change = "added last_log_id arg")]
pub fn new(from: VoteOf<C>, to: C::NodeId, last_log_id: Option<LogIdOf<C>>) -> Self {
Self {
from_leader: from,
to_node_id: to,
last_log_id,
}
}
pub fn from_leader(&self) -> &VoteOf<C> {
&self.from_leader
}
pub fn to_node_id(&self) -> &C::NodeId {
&self.to_node_id
}
#[since(version = "0.10.0")]
pub fn last_log_id(&self) -> Option<&LogIdOf<C>> {
self.last_log_id.as_ref()
}
}
#[since(version = "0.10.0")]
pub type TransferLeaderResponse<C> = Result<(), TransferLeaderError<C>>;
#[since(version = "0.10.0")]
#[derive(Clone, Debug)]
#[derive(PartialEq, Eq)]
#[derive(thiserror::Error)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize), serde(bound = ""))]
pub enum TransferLeaderError<C>
where C: RaftTypeConfig
{
#[error("transfer leader rejected because vote changed; expected: {expected:?}, actual: {actual:?}")]
VoteChanged {
expected: VoteOf<C>,
actual: VoteOf<C>,
},
#[error("transfer leader rejected because log is not flushed; expected: {expected:?}, actual: {actual:?}")]
LogNotFlushed {
expected: Option<LogIdOf<C>>,
actual: Option<LogIdOf<C>>,
},
}
impl<C> fmt::Display for TransferLeaderRequest<C>
where C: RaftTypeConfig
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"(from_leader={}, to={}, last_log_id={})",
self.from_leader,
self.to_node_id,
self.last_log_id.display()
)
}
}