use std::collections::BTreeMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Owner {
Salesforce,
Postgres,
Shared,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ConflictPolicy {
FieldOwnership,
#[default]
ManualReview,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LaneThresholds {
rest_max_batch_size: usize,
bulk_min_batch_size: usize,
}
impl LaneThresholds {
#[must_use]
pub const fn rest_max_batch_size(&self) -> usize {
self.rest_max_batch_size
}
#[must_use]
pub const fn bulk_min_batch_size(&self) -> usize {
self.bulk_min_batch_size
}
}
impl Default for LaneThresholds {
fn default() -> Self {
Self {
rest_max_batch_size: 25,
bulk_min_batch_size: 500,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ObjectSync {
object_name: String,
external_id_field: Option<String>,
conflict_policy: ConflictPolicy,
lane_thresholds: LaneThresholds,
field_ownership: BTreeMap<String, Owner>,
}
impl ObjectSync {
#[must_use]
pub fn new(object_name: impl Into<String>) -> Self {
Self {
object_name: object_name.into(),
external_id_field: None,
conflict_policy: ConflictPolicy::default(),
lane_thresholds: LaneThresholds::default(),
field_ownership: BTreeMap::new(),
}
}
#[must_use]
pub fn external_id(mut self, external_id_field: impl Into<String>) -> Self {
self.external_id_field = Some(external_id_field.into());
self
}
#[must_use]
pub fn field_owner(mut self, field_name: impl Into<String>, owner: Owner) -> Self {
self.field_ownership.insert(field_name.into(), owner);
self
}
#[must_use]
pub fn object_name(&self) -> &str {
&self.object_name
}
#[must_use]
pub fn external_id_field(&self) -> Option<&str> {
self.external_id_field.as_deref()
}
#[must_use]
pub const fn conflict_policy(&self) -> &ConflictPolicy {
&self.conflict_policy
}
#[must_use]
pub const fn lane_thresholds(&self) -> &LaneThresholds {
&self.lane_thresholds
}
#[must_use]
pub fn field_owner_for(&self, field_name: &str) -> Option<Owner> {
self.field_ownership.get(field_name).copied()
}
#[must_use]
pub const fn field_ownership(&self) -> &BTreeMap<String, Owner> {
&self.field_ownership
}
}
#[cfg(test)]
mod tests {
use super::{ObjectSync, Owner};
#[test]
fn object_sync_external_id_builder_stores_config() {
let config = ObjectSync::new("Account").external_id("External_Id__c");
assert_eq!(config.object_name(), "Account");
assert_eq!(config.external_id_field(), Some("External_Id__c"));
}
#[test]
fn object_sync_field_owner_builder_stores_rules() {
let config = ObjectSync::new("Account").field_owner("Name", Owner::Postgres);
assert_eq!(config.field_owner_for("Name"), Some(Owner::Postgres));
assert_eq!(config.field_ownership().len(), 1);
}
}