use core::ops::Deref;
use cu29_clock::{RobotClock, RobotClockMock};
#[derive(Clone, Debug)]
pub struct CuContext {
pub clock: RobotClock,
cl_id: u64,
instance_id: u32,
subsystem_code: u16,
task_ids: &'static [&'static str],
current_task_index: Option<usize>,
}
impl CuContext {
pub fn builder(clock: RobotClock) -> CuContextBuilder {
CuContextBuilder {
clock,
cl_id: 0,
instance_id: 0,
subsystem_code: 0,
task_ids: &[],
}
}
pub fn from_clock(clock: RobotClock) -> Self {
Self::builder(clock).build()
}
#[cfg(feature = "std")]
pub fn new_with_clock() -> Self {
Self::from_clock(RobotClock::new())
}
pub fn new_mock_clock() -> (Self, RobotClockMock) {
let (clock, mock) = RobotClock::mock();
(Self::from_clock(clock), mock)
}
pub(crate) fn new(
clock: RobotClock,
clid: u64,
instance_id: u32,
subsystem_code: u16,
task_ids: &'static [&'static str],
) -> Self {
Self {
clock,
cl_id: clid,
instance_id,
subsystem_code,
task_ids,
current_task_index: None,
}
}
#[doc(hidden)]
pub fn from_runtime_metadata(
clock: RobotClock,
clid: u64,
instance_id: u32,
subsystem_code: u16,
task_ids: &'static [&'static str],
) -> Self {
Self::new(clock, clid, instance_id, subsystem_code, task_ids)
}
pub fn set_current_task(&mut self, task_index: usize) {
self.current_task_index = Some(task_index);
}
pub fn clear_current_task(&mut self) {
self.current_task_index = None;
}
pub fn cl_id(&self) -> u64 {
self.cl_id
}
pub fn instance_id(&self) -> u32 {
self.instance_id
}
pub fn subsystem_code(&self) -> u16 {
self.subsystem_code
}
pub fn task_index(&self) -> Option<usize> {
self.current_task_index
}
pub fn task_id(&self) -> Option<&'static str> {
self.current_task_index
.and_then(|idx| self.task_ids.get(idx).copied())
}
}
#[derive(Clone, Debug)]
pub struct CuContextBuilder {
clock: RobotClock,
cl_id: u64,
instance_id: u32,
subsystem_code: u16,
task_ids: &'static [&'static str],
}
impl CuContextBuilder {
pub fn cl_id(mut self, cl_id: u64) -> Self {
self.cl_id = cl_id;
self
}
pub fn instance_id(mut self, instance_id: u32) -> Self {
self.instance_id = instance_id;
self
}
pub fn task_ids(mut self, task_ids: &'static [&'static str]) -> Self {
self.task_ids = task_ids;
self
}
pub fn build(self) -> CuContext {
CuContext::new(
self.clock,
self.cl_id,
self.instance_id,
self.subsystem_code,
self.task_ids,
)
}
}
impl Deref for CuContext {
type Target = RobotClock;
fn deref(&self) -> &Self::Target {
&self.clock
}
}
#[cfg(test)]
mod tests {
use super::CuContext;
use cu29_clock::RobotClock;
#[test]
fn default_instance_id_is_zero() {
let ctx = CuContext::from_clock(RobotClock::default());
assert_eq!(ctx.instance_id(), 0);
assert_eq!(ctx.subsystem_code(), 0);
}
#[test]
fn builder_overrides_instance_id() {
let ctx = CuContext::builder(RobotClock::default())
.cl_id(7)
.instance_id(42)
.build();
assert_eq!(ctx.cl_id(), 7);
assert_eq!(ctx.instance_id(), 42);
assert_eq!(ctx.subsystem_code(), 0);
}
#[test]
fn runtime_metadata_sets_subsystem_code() {
let ctx = CuContext::from_runtime_metadata(RobotClock::default(), 9, 42, 7, &[]);
assert_eq!(ctx.cl_id(), 9);
assert_eq!(ctx.instance_id(), 42);
assert_eq!(ctx.subsystem_code(), 7);
}
}