use serde::{ser::SerializeStruct, Deserialize, Serialize};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct GetBlockQuery {
pub expand: BlockExpansion,
pub kind: BlockKind,
}
impl GetBlockQuery {
pub const fn new(expand: BlockExpansion) -> Self {
Self { expand, kind: BlockKind::Canonical }
}
pub const fn with_all(self) -> Self {
Self { expand: BlockExpansion::all(), ..self }
}
pub const fn with_none(self) -> Self {
Self { expand: BlockExpansion::none(), ..self }
}
pub const fn reorged(self) -> Self {
Self { kind: BlockKind::Reorged, ..self }
}
pub const fn with_transaction(self) -> Self {
Self { expand: self.expand.with_transaction(), ..self }
}
pub const fn no_transactions(self) -> Self {
Self { expand: self.expand.no_transactions(), ..self }
}
pub const fn with_blob(self) -> Self {
Self { expand: self.expand.with_blob(), ..self }
}
pub const fn no_blob(self) -> Self {
Self { expand: self.expand.no_blob(), ..self }
}
pub const fn with_blob_data(self) -> Self {
Self { expand: self.expand.with_blob_data(), ..self }
}
pub const fn no_blob_data(self) -> Self {
Self { expand: self.expand.no_blob_data(), ..self }
}
}
impl Serialize for GetBlockQuery {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut s = serializer.serialize_struct("GetBlockQuery", 2)?;
let expand = self.expand.query_string();
if !expand.is_empty() {
s.serialize_field("expand", &expand)?;
}
s.serialize_field("type", &self.kind)?;
s.end()
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum BlockKind {
#[default]
#[serde(rename = "canonical")]
Canonical,
#[serde(rename = "reorged")]
Reorged,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct BlockExpansion {
pub transaction: bool,
pub blob: bool,
pub blob_data: bool,
}
impl BlockExpansion {
pub const fn all() -> Self {
Self { transaction: true, blob: true, blob_data: true }
}
pub const fn none() -> Self {
Self { transaction: false, blob: false, blob_data: false }
}
pub fn query_string(self) -> String {
let Self { transaction, blob, blob_data } = self;
transaction
.then_some("transaction")
.into_iter()
.chain(blob.then_some("blob"))
.chain(blob_data.then_some("blob_data"))
.collect::<Vec<_>>()
.join(",")
}
pub const fn no_blob_data(self) -> Self {
Self { blob_data: false, ..self }
}
pub const fn no_transactions(self) -> Self {
Self { transaction: false, ..self }
}
pub const fn no_blob(self) -> Self {
Self { blob: false, ..self }
}
pub const fn with_transaction(self) -> Self {
Self { transaction: true, ..self }
}
pub const fn with_blob(self) -> Self {
Self { blob: true, ..self }
}
pub const fn with_blob_data(self) -> Self {
Self { blob_data: true, ..self }
}
}
impl Default for BlockExpansion {
fn default() -> Self {
Self::all()
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct GetTransactionQuery {
pub block: bool,
pub blob: bool,
pub blob_data: bool,
}
impl GetTransactionQuery {
pub const fn all() -> Self {
Self { block: true, blob: true, blob_data: true }
}
pub const fn none() -> Self {
Self { block: false, blob: false, blob_data: false }
}
pub fn query_string(self) -> String {
let Self { block, blob, blob_data } = self;
block
.then_some("block")
.into_iter()
.chain(blob.then_some("blob"))
.chain(blob_data.then_some("blob_data"))
.collect::<Vec<_>>()
.join(",")
}
pub const fn no_blob_data(self) -> Self {
Self { blob_data: false, ..self }
}
pub const fn no_block(self) -> Self {
Self { block: false, ..self }
}
pub const fn no_blob(self) -> Self {
Self { blob: false, ..self }
}
}
impl Default for GetTransactionQuery {
fn default() -> Self {
Self::all()
}
}
impl Serialize for GetTransactionQuery {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut s = serializer.serialize_struct("GetTransactionQuery", 1)?;
let expand = self.query_string();
if !expand.is_empty() {
s.serialize_field("expand", &expand)?;
}
s.end()
}
}