pub mod data_types;
pub mod describe;
pub mod get_pending;
pub mod start_next;
pub mod subscribe;
pub mod unsubscribe;
pub mod update;
use core::fmt::Write;
use self::{
data_types::JobStatus, describe::Describe, get_pending::GetPending, start_next::StartNext,
subscribe::Subscribe, unsubscribe::Unsubscribe, update::Update,
};
pub use subscribe::Topic;
pub const MAX_THING_NAME_LEN: usize = 128;
pub const MAX_CLIENT_TOKEN_LEN: usize = MAX_THING_NAME_LEN + 10;
pub const MAX_JOB_ID_LEN: usize = 64;
pub const MAX_STREAM_ID_LEN: usize = MAX_JOB_ID_LEN;
pub const MAX_PENDING_JOBS: usize = 1;
pub const MAX_RUNNING_JOBS: usize = 1;
pub type StatusDetails<'a> = heapless::LinearMap<&'a str, &'a str, 4>;
pub type StatusDetailsOwned = heapless::LinearMap<heapless::String<15>, heapless::String<11>, 4>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum JobError {
Overflow,
Encoding,
Mqtt(mqttrust::MqttError),
}
impl From<mqttrust::MqttError> for JobError {
fn from(e: mqttrust::MqttError) -> Self {
Self::Mqtt(e)
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum JobTopic<'a> {
GetNext,
GetPending,
StartNext,
Get(&'a str),
Update(&'a str),
Notify,
NotifyNext,
GetAccepted,
GetRejected,
StartNextAccepted,
StartNextRejected,
DescribeAccepted(&'a str),
DescribeRejected(&'a str),
UpdateAccepted(&'a str),
UpdateRejected(&'a str),
}
impl<'a> JobTopic<'a> {
const PREFIX: &'static str = "$aws/things";
pub fn check(s: &'a str) -> bool {
s.starts_with(Self::PREFIX)
}
pub fn format<const L: usize>(&self, client_id: &str) -> Result<heapless::String<L>, JobError> {
let mut topic_path = heapless::String::new();
match self {
Self::GetNext => topic_path.write_fmt(format_args!(
"{}/{}/jobs/$next/get",
Self::PREFIX,
client_id
)),
Self::GetPending => {
topic_path.write_fmt(format_args!("{}/{}/jobs/get", Self::PREFIX, client_id))
}
Self::StartNext => topic_path.write_fmt(format_args!(
"{}/{}/jobs/start-next",
Self::PREFIX,
client_id
)),
Self::Get(job_id) => topic_path.write_fmt(format_args!(
"{}/{}/jobs/{}/get",
Self::PREFIX,
client_id,
job_id
)),
Self::Update(job_id) => topic_path.write_fmt(format_args!(
"{}/{}/jobs/{}/update",
Self::PREFIX,
client_id,
job_id
)),
Self::Notify => {
topic_path.write_fmt(format_args!("{}/{}/jobs/notify", Self::PREFIX, client_id))
}
Self::NotifyNext => topic_path.write_fmt(format_args!(
"{}/{}/jobs/notify-next",
Self::PREFIX,
client_id
)),
Self::GetAccepted => topic_path.write_fmt(format_args!(
"{}/{}/jobs/get/accepted",
Self::PREFIX,
client_id
)),
Self::GetRejected => topic_path.write_fmt(format_args!(
"{}/{}/jobs/get/rejected",
Self::PREFIX,
client_id
)),
Self::StartNextAccepted => topic_path.write_fmt(format_args!(
"{}/{}/jobs/start-next/accepted",
Self::PREFIX,
client_id
)),
Self::StartNextRejected => topic_path.write_fmt(format_args!(
"{}/{}/jobs/start-next/rejected",
Self::PREFIX,
client_id
)),
Self::DescribeAccepted(job_id) => topic_path.write_fmt(format_args!(
"{}/{}/jobs/{}/get/accepted",
Self::PREFIX,
client_id,
job_id
)),
Self::DescribeRejected(job_id) => topic_path.write_fmt(format_args!(
"{}/{}/jobs/{}/get/rejected",
Self::PREFIX,
client_id,
job_id
)),
Self::UpdateAccepted(job_id) => topic_path.write_fmt(format_args!(
"{}/{}/jobs/{}/update/accepted",
Self::PREFIX,
client_id,
job_id
)),
Self::UpdateRejected(job_id) => topic_path.write_fmt(format_args!(
"{}/{}/jobs/{}/update/rejected",
Self::PREFIX,
client_id,
job_id
)),
}
.map_err(|_| JobError::Overflow)?;
Ok(topic_path)
}
}
pub struct Jobs;
impl Jobs {
pub fn get_pending<'a>() -> GetPending<'a> {
GetPending::new()
}
pub fn start_next<'a>() -> StartNext<'a> {
StartNext::new()
}
pub fn describe<'a>() -> Describe<'a> {
Describe::new()
}
pub fn update(job_id: &str, status: JobStatus) -> Update {
Update::new(job_id, status)
}
pub fn subscribe<'a, const N: usize>() -> Subscribe<'a, N> {
Subscribe::new()
}
pub fn unsubscribe<'a, const N: usize>() -> Unsubscribe<'a, N> {
Unsubscribe::new()
}
}