templar_curator_primitives/policy/target_set/
mod.rs

1use alloc::vec::Vec;
2use templar_vault_kernel::{DurationNs, TargetId, TimestampNs};
3
4use super::{
5    refresh_plan::{refresh_execution_plan, RefreshExecutionPlan, RefreshPlanError, RefreshTiming},
6    withdraw_route::{withdraw_plan_from_principals, WithdrawPlanEntry, WithdrawRouteError},
7};
8
9#[must_use]
10pub fn find_first_duplicate<T: PartialEq + Copy>(items: &[T]) -> Option<T> {
11    for (index, item) in items.iter().enumerate() {
12        if items[index + 1..].contains(item) {
13            return Some(*item);
14        }
15    }
16
17    None
18}
19
20#[must_use]
21pub fn has_unique_items<T: PartialEq + Copy>(items: &[T]) -> bool {
22    find_first_duplicate(items).is_none()
23}
24
25pub fn build_withdraw_capacity_pairs_from_target_principals(
26    principals: &[(TargetId, u128)],
27    target_amount: u128,
28) -> Result<Vec<(TargetId, u128)>, WithdrawRouteError> {
29    withdraw_plan_from_principals(principals, target_amount)
30        .map(|plan| plan.into_iter().map(Into::into).collect())
31}
32
33pub fn withdraw_plan(
34    principals: &[(TargetId, u128)],
35    target_amount: u128,
36) -> Result<Vec<WithdrawPlanEntry>, WithdrawRouteError> {
37    withdraw_plan_from_principals(principals, target_amount)
38}
39
40pub fn build_refresh_plan_from_targets(
41    targets: &[TargetId],
42    cooldown: DurationNs,
43    last_refresh_at: Option<TimestampNs>,
44) -> Result<
45    (
46        super::refresh_plan::RefreshPlan,
47        super::refresh_plan::RefreshThrottle,
48    ),
49    RefreshPlanError,
50> {
51    refresh_execution_plan(targets, RefreshTiming::new(cooldown, last_refresh_at))
52        .map(RefreshExecutionPlan::into_parts)
53}
54
55pub fn refresh_plan(
56    targets: &[TargetId],
57    cooldown: DurationNs,
58    last_refresh_at: Option<TimestampNs>,
59) -> Result<RefreshExecutionPlan, RefreshPlanError> {
60    refresh_execution_plan(targets, RefreshTiming::new(cooldown, last_refresh_at))
61}
62
63pub fn refresh_plan_with_timing(
64    targets: &[TargetId],
65    timing: RefreshTiming,
66) -> Result<RefreshExecutionPlan, RefreshPlanError> {
67    refresh_execution_plan(targets, timing)
68}