use super::EffectGraphError;
use crate::model::bounded_sequence;
use serde::{Deserialize, Deserializer, Serialize};
pub const MAX_EFFECT_DEPENDENCIES: usize = 1024;
#[derive(Clone, Debug)]
pub struct EffectNodeRequest {
pub operation_sequence: u64,
pub depends_on: Vec<u64>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(try_from = "NodeFields")]
pub struct EffectNodeRecord {
operation_sequence: u64,
depends_on: Vec<u64>,
}
#[derive(Deserialize)]
#[serde(deny_unknown_fields)]
struct NodeFields {
operation_sequence: u64,
#[serde(deserialize_with = "bounded_dependencies")]
depends_on: Vec<u64>,
}
impl TryFrom<NodeFields> for EffectNodeRecord {
type Error = EffectGraphError;
fn try_from(fields: NodeFields) -> Result<Self, Self::Error> {
Self::new(EffectNodeRequest {
operation_sequence: fields.operation_sequence,
depends_on: fields.depends_on,
})
}
}
impl EffectNodeRecord {
pub fn new(mut request: EffectNodeRequest) -> Result<Self, EffectGraphError> {
if request.depends_on.len() > MAX_EFFECT_DEPENDENCIES {
return Err(EffectGraphError::TooManyDependencies);
}
request.depends_on.sort_unstable();
for pair in request.depends_on.windows(2) {
if pair[0] == pair[1] {
return Err(EffectGraphError::DuplicateDependency {
operation_sequence: request.operation_sequence,
dependency: pair[0],
});
}
}
Ok(Self {
operation_sequence: request.operation_sequence,
depends_on: request.depends_on,
})
}
#[must_use]
pub const fn operation_sequence(&self) -> u64 {
self.operation_sequence
}
#[must_use]
pub fn depends_on(&self) -> &[u64] {
&self.depends_on
}
}
fn bounded_dependencies<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u64>, D::Error> {
bounded_sequence::deserialize::<_, _, MAX_EFFECT_DEPENDENCIES>(
deserializer,
"bounded exact effect dependencies",
EffectGraphError::TooManyDependencies,
)
}