use std::sync::{Arc, LazyLock};
use std::time::Duration;
use bacnet_objects::clock::{ClockFrame, ClockReader};
use bacnet_objects::property_metadata::{
PropertyConformance, PropertyMetadata, PropertyWriteCapability,
};
use bacnet_objects::schedule::ScheduleWrite;
use bacnet_objects::traits::{DeadlineWaker, MonotonicClock};
use bacnet_types::calendar::SpecificDate;
use bacnet_types::enums::{ErrorClass, ErrorCode, ObjectType, PropertyIdentifier as P};
use bacnet_types::error::Error;
use bacnet_types::primitives::{ObjectIdentifier, PropertyValue, Time};
pub fn day() -> SpecificDate {
SpecificDate::new(2026, 10, 2).unwrap()
}
pub fn noon() -> Time {
Time {
hour: 12,
minute: 0,
second: 0,
hundredths: 0,
}
}
pub fn oid(object_type: ObjectType, instance: u32) -> ObjectIdentifier {
ObjectIdentifier::new(object_type, instance).unwrap()
}
pub fn property_error(code: ErrorCode) -> Error {
Error::Protocol {
class: ErrorClass::PROPERTY.to_raw() as u32,
code: code.to_raw() as u32,
}
}
struct NoClock;
impl ClockReader for NoClock {
fn read_clock(&self) -> Option<ClockFrame> {
None
}
}
static CLOCK: LazyLock<Arc<dyn ClockReader>> = LazyLock::new(|| Arc::new(NoClock));
static MONOTONIC: LazyLock<Arc<MonotonicClock>> =
LazyLock::new(|| Arc::new(|| Duration::from_secs(99)));
pub fn clock() -> Arc<dyn ClockReader> {
CLOCK.clone()
}
pub fn monotonic() -> Arc<MonotonicClock> {
MONOTONIC.clone()
}
static WAKER: LazyLock<Arc<DeadlineWaker>> = LazyLock::new(|| Arc::new(|| {}));
pub fn waker() -> Arc<DeadlineWaker> {
WAKER.clone()
}
pub fn address<T: ?Sized>(reference: &T) -> String {
format!("{:p}", std::ptr::from_ref(reference).cast::<()>())
}
pub fn schedule_write(value: u64) -> ScheduleWrite {
ScheduleWrite {
value: PropertyValue::Unsigned(value),
priority: 16,
references: Vec::new(),
retry: false,
}
}
pub const METADATA: [PropertyMetadata; 5] = [
PropertyMetadata::new(
P::OBJECT_IDENTIFIER,
PropertyConformance::RequiredRead,
None,
PropertyWriteCapability::ReadOnly,
),
PropertyMetadata::new(
P::OBJECT_NAME,
PropertyConformance::RequiredRead,
None,
PropertyWriteCapability::ReadOnly,
),
PropertyMetadata::new(
P::OBJECT_TYPE,
PropertyConformance::RequiredRead,
None,
PropertyWriteCapability::ReadOnly,
),
PropertyMetadata::new(
P::DESCRIPTION,
PropertyConformance::Optional,
None,
PropertyWriteCapability::Always,
),
PropertyMetadata::new(
P::PROPERTY_LIST,
PropertyConformance::RequiredRead,
None,
PropertyWriteCapability::ReadOnly,
),
];