pdk-contracts-lib 1.9.1-alpha.2

PDK Contracts Library
Documentation
// Copyright (c) 2026, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

use std::{cell::RefCell, collections::HashMap, time::SystemTime};

use pdk_core::classy::{proxy_wasm::types::Status, Clock, SharedData};

pub struct ManualClock {
    current: SystemTime,
}

impl ManualClock {
    fn new() -> Self {
        Self {
            current: SystemTime::now(),
        }
    }
}

impl Default for ManualClock {
    /// Returns the manual clock implementation that is useful for testing
    fn default() -> Self {
        Self::new()
    }
}

impl Clock for ManualClock {
    fn get_current_time(&self) -> SystemTime {
        self.current
    }
}

#[derive(Default)]
pub struct MapSharedData {
    map: RefCell<HashMap<String, MapSharedDataEntry>>,
}

struct MapSharedDataEntry {
    data: Option<Vec<u8>>,
    lock: u32,
}

impl MapSharedData {
    fn do_store(&self, key: &str, value: &[u8], version: u32) {
        self.map.borrow_mut().insert(
            key.to_string(),
            MapSharedDataEntry {
                data: Some(value.to_vec()),
                lock: version,
            },
        );
    }

    fn next_cas(cas: Option<u32>) -> u32 {
        match cas {
            Some(u32::MAX) | None => 1,
            Some(cas) => cas + 1,
        }
    }
}

impl SharedData for MapSharedData {
    fn shared_data_get(&self, key: &str) -> (Option<Vec<u8>>, Option<u32>) {
        let key = key.to_string();
        self.map
            .borrow()
            .get(&key)
            .map(|entry| (entry.data.clone(), Some(entry.lock)))
            .unwrap_or_else(|| (None, None))
    }

    fn shared_data_set(&self, key: &str, value: &[u8], version: Option<u32>) -> Result<(), Status> {
        let (_, lock) = self.shared_data_get(key);
        if version.is_none() || lock.is_none() || version.unwrap() == lock.unwrap() {
            self.do_store(key, value, Self::next_cas(version));
            Ok(())
        } else {
            Err(Status::CasMismatch)
        }
    }

    fn shared_data_remove(
        &self,
        key: &str,
        version: Option<u32>,
    ) -> Result<Option<Vec<u8>>, Status> {
        let (val, _) = self.shared_data_get(key);
        self.shared_data_set(key, &[], version)?;
        Ok(val)
    }

    fn shared_data_keys(&self) -> Vec<String> {
        self.map.borrow().keys().cloned().collect()
    }
}