#[allow(unused_imports)]
use alloc::collections::BTreeMap;
#[allow(unused_imports)]
use core::marker::PhantomData;
use jacquard_common::CowStr;
use jacquard_common::deps::bytes::Bytes;
#[allow(unused_imports)]
use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
use jacquard_common::types::string::{Did, UriValue};
use jacquard_derive::{IntoStatic, lexicon, open_union};
use jacquard_lexicon::lexicon::LexiconDoc;
use jacquard_lexicon::schema::LexiconSchema;
#[allow(unused_imports)]
use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
use serde::{Serialize, Deserialize};
use crate::io_atcr::hold::subscribe_scan_jobs;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct SubscribeScanJobs {
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<i64>,
}
#[open_union]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(tag = "$type")]
#[serde(bound(deserialize = "'de: 'a"))]
pub enum SubscribeScanJobsMessage<'a> {
#[serde(rename = "#scanJob")]
ScanJob(Box<subscribe_scan_jobs::ScanJob<'a>>),
#[serde(rename = "#scanResult")]
ScanResult(Box<subscribe_scan_jobs::ScanResult<'a>>),
}
impl<'a> SubscribeScanJobsMessage<'a> {
pub fn decode_framed<'de: 'a>(
bytes: &'de [u8],
) -> Result<SubscribeScanJobsMessage<'a>, jacquard_common::error::DecodeError> {
let (header, body) = jacquard_common::xrpc::subscription::parse_event_header(
bytes,
)?;
match header.t.as_str() {
"#scanJob" => {
let variant = jacquard_common::deps::codegen::serde_ipld_dagcbor::from_slice(
body,
)?;
Ok(Self::ScanJob(Box::new(variant)))
}
"#scanResult" => {
let variant = jacquard_common::deps::codegen::serde_ipld_dagcbor::from_slice(
body,
)?;
Ok(Self::ScanResult(Box::new(variant)))
}
unknown => {
Err(
jacquard_common::error::DecodeError::UnknownEventType(unknown.into()),
)
}
}
}
}
#[open_union]
#[derive(
Serialize,
Deserialize,
Debug,
Clone,
PartialEq,
Eq,
thiserror::Error,
miette::Diagnostic,
IntoStatic
)]
#[serde(tag = "error", content = "message")]
#[serde(bound(deserialize = "'de: 'a"))]
pub enum SubscribeScanJobsError<'a> {
#[serde(rename = "InvalidSecret")]
InvalidSecret(Option<CowStr<'a>>),
}
impl core::fmt::Display for SubscribeScanJobsError<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::InvalidSecret(msg) => {
write!(f, "InvalidSecret")?;
if let Some(msg) = msg {
write!(f, ": {}", msg)?;
}
Ok(())
}
Self::Unknown(err) => write!(f, "Unknown error: {:?}", err),
}
}
}
#[lexicon]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct ScanJob<'a> {
#[serde(borrow)]
pub digest: CowStr<'a>,
#[serde(borrow)]
pub hold_did: Did<'a>,
#[serde(borrow)]
pub hold_endpoint: UriValue<'a>,
#[serde(skip_serializing_if = "Option::is_none")]
pub priority: Option<i64>,
#[serde(borrow)]
pub repository: CowStr<'a>,
pub seq: i64,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub tag: Option<CowStr<'a>>,
#[serde(borrow)]
pub r#type: CowStr<'a>,
#[serde(borrow)]
pub user_did: Did<'a>,
}
#[lexicon]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct ScanResult<'a> {
#[serde(borrow)]
pub digest: CowStr<'a>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub error: Option<CowStr<'a>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default, with = "jacquard_common::opt_serde_bytes_helper")]
pub sbom: Option<Bytes>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub scanner_version: Option<CowStr<'a>>,
#[serde(borrow)]
pub summary: subscribe_scan_jobs::VulnSummary<'a>,
#[serde(borrow)]
pub r#type: CowStr<'a>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default, with = "jacquard_common::opt_serde_bytes_helper")]
pub vuln_report: Option<Bytes>,
}
#[lexicon]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct VulnSummary<'a> {
pub critical: i64,
pub high: i64,
pub low: i64,
pub medium: i64,
pub total: i64,
}
pub struct SubscribeScanJobsStream;
impl jacquard_common::xrpc::SubscriptionResp for SubscribeScanJobsStream {
const NSID: &'static str = "io.atcr.hold.subscribeScanJobs";
const ENCODING: jacquard_common::xrpc::MessageEncoding = jacquard_common::xrpc::MessageEncoding::Json;
type Message<'de> = SubscribeScanJobsMessage<'de>;
type Error<'de> = SubscribeScanJobsError<'de>;
}
impl jacquard_common::xrpc::XrpcSubscription for SubscribeScanJobs {
const NSID: &'static str = "io.atcr.hold.subscribeScanJobs";
const ENCODING: jacquard_common::xrpc::MessageEncoding = jacquard_common::xrpc::MessageEncoding::Json;
type Stream = SubscribeScanJobsStream;
}
pub struct SubscribeScanJobsEndpoint;
impl jacquard_common::xrpc::SubscriptionEndpoint for SubscribeScanJobsEndpoint {
const PATH: &'static str = "/xrpc/io.atcr.hold.subscribeScanJobs";
const ENCODING: jacquard_common::xrpc::MessageEncoding = jacquard_common::xrpc::MessageEncoding::Json;
type Params<'de> = SubscribeScanJobs;
type Stream = SubscribeScanJobsStream;
}
impl<'a> LexiconSchema for ScanJob<'a> {
fn nsid() -> &'static str {
"io.atcr.hold.subscribeScanJobs"
}
fn def_name() -> &'static str {
"scanJob"
}
fn lexicon_doc() -> LexiconDoc<'static> {
lexicon_doc_io_atcr_hold_subscribeScanJobs()
}
fn validate(&self) -> Result<(), ConstraintError> {
{
let value = &self.digest;
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 128usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("digest"),
max: 128usize,
actual: <str>::len(value.as_ref()),
});
}
}
{
let value = &self.repository;
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 256usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("repository"),
max: 256usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.tag {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 256usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("tag"),
max: 256usize,
actual: <str>::len(value.as_ref()),
});
}
}
{
let value = &self.r#type;
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 32usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("type"),
max: 32usize,
actual: <str>::len(value.as_ref()),
});
}
}
Ok(())
}
}
impl<'a> LexiconSchema for ScanResult<'a> {
fn nsid() -> &'static str {
"io.atcr.hold.subscribeScanJobs"
}
fn def_name() -> &'static str {
"scanResult"
}
fn lexicon_doc() -> LexiconDoc<'static> {
lexicon_doc_io_atcr_hold_subscribeScanJobs()
}
fn validate(&self) -> Result<(), ConstraintError> {
{
let value = &self.digest;
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 128usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("digest"),
max: 128usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.error {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 1024usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("error"),
max: 1024usize,
actual: <str>::len(value.as_ref()),
});
}
}
if let Some(ref value) = self.scanner_version {
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 64usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("scanner_version"),
max: 64usize,
actual: <str>::len(value.as_ref()),
});
}
}
{
let value = &self.r#type;
#[allow(unused_comparisons)]
if <str>::len(value.as_ref()) > 32usize {
return Err(ConstraintError::MaxLength {
path: ValidationPath::from_field("type"),
max: 32usize,
actual: <str>::len(value.as_ref()),
});
}
}
Ok(())
}
}
impl<'a> LexiconSchema for VulnSummary<'a> {
fn nsid() -> &'static str {
"io.atcr.hold.subscribeScanJobs"
}
fn def_name() -> &'static str {
"vulnSummary"
}
fn lexicon_doc() -> LexiconDoc<'static> {
lexicon_doc_io_atcr_hold_subscribeScanJobs()
}
fn validate(&self) -> Result<(), ConstraintError> {
{
let value = &self.critical;
if *value < 0i64 {
return Err(ConstraintError::Minimum {
path: ValidationPath::from_field("critical"),
min: 0i64,
actual: *value,
});
}
}
{
let value = &self.high;
if *value < 0i64 {
return Err(ConstraintError::Minimum {
path: ValidationPath::from_field("high"),
min: 0i64,
actual: *value,
});
}
}
{
let value = &self.low;
if *value < 0i64 {
return Err(ConstraintError::Minimum {
path: ValidationPath::from_field("low"),
min: 0i64,
actual: *value,
});
}
}
{
let value = &self.medium;
if *value < 0i64 {
return Err(ConstraintError::Minimum {
path: ValidationPath::from_field("medium"),
min: 0i64,
actual: *value,
});
}
}
{
let value = &self.total;
if *value < 0i64 {
return Err(ConstraintError::Minimum {
path: ValidationPath::from_field("total"),
min: 0i64,
actual: *value,
});
}
}
Ok(())
}
}
pub mod subscribe_scan_jobs_state {
pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
#[allow(unused)]
use ::core::marker::PhantomData;
mod sealed {
pub trait Sealed {}
}
pub trait State: sealed::Sealed {}
pub struct Empty(());
impl sealed::Sealed for Empty {}
impl State for Empty {}
#[allow(non_camel_case_types)]
pub mod members {}
}
pub struct SubscribeScanJobsBuilder<S: subscribe_scan_jobs_state::State> {
_state: PhantomData<fn() -> S>,
_fields: (Option<i64>,),
}
impl SubscribeScanJobs {
pub fn new() -> SubscribeScanJobsBuilder<subscribe_scan_jobs_state::Empty> {
SubscribeScanJobsBuilder::new()
}
}
impl SubscribeScanJobsBuilder<subscribe_scan_jobs_state::Empty> {
pub fn new() -> Self {
SubscribeScanJobsBuilder {
_state: PhantomData,
_fields: (None,),
}
}
}
impl<S: subscribe_scan_jobs_state::State> SubscribeScanJobsBuilder<S> {
pub fn cursor(mut self, value: impl Into<Option<i64>>) -> Self {
self._fields.0 = value.into();
self
}
pub fn maybe_cursor(mut self, value: Option<i64>) -> Self {
self._fields.0 = value;
self
}
}
impl<S> SubscribeScanJobsBuilder<S>
where
S: subscribe_scan_jobs_state::State,
{
pub fn build(self) -> SubscribeScanJobs {
SubscribeScanJobs {
cursor: self._fields.0,
}
}
}
pub mod scan_job_state {
pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
#[allow(unused)]
use ::core::marker::PhantomData;
mod sealed {
pub trait Sealed {}
}
pub trait State: sealed::Sealed {
type HoldEndpoint;
type HoldDid;
type Type;
type Digest;
type Seq;
type UserDid;
type Repository;
}
pub struct Empty(());
impl sealed::Sealed for Empty {}
impl State for Empty {
type HoldEndpoint = Unset;
type HoldDid = Unset;
type Type = Unset;
type Digest = Unset;
type Seq = Unset;
type UserDid = Unset;
type Repository = Unset;
}
pub struct SetHoldEndpoint<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetHoldEndpoint<S> {}
impl<S: State> State for SetHoldEndpoint<S> {
type HoldEndpoint = Set<members::hold_endpoint>;
type HoldDid = S::HoldDid;
type Type = S::Type;
type Digest = S::Digest;
type Seq = S::Seq;
type UserDid = S::UserDid;
type Repository = S::Repository;
}
pub struct SetHoldDid<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetHoldDid<S> {}
impl<S: State> State for SetHoldDid<S> {
type HoldEndpoint = S::HoldEndpoint;
type HoldDid = Set<members::hold_did>;
type Type = S::Type;
type Digest = S::Digest;
type Seq = S::Seq;
type UserDid = S::UserDid;
type Repository = S::Repository;
}
pub struct SetType<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetType<S> {}
impl<S: State> State for SetType<S> {
type HoldEndpoint = S::HoldEndpoint;
type HoldDid = S::HoldDid;
type Type = Set<members::r#type>;
type Digest = S::Digest;
type Seq = S::Seq;
type UserDid = S::UserDid;
type Repository = S::Repository;
}
pub struct SetDigest<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetDigest<S> {}
impl<S: State> State for SetDigest<S> {
type HoldEndpoint = S::HoldEndpoint;
type HoldDid = S::HoldDid;
type Type = S::Type;
type Digest = Set<members::digest>;
type Seq = S::Seq;
type UserDid = S::UserDid;
type Repository = S::Repository;
}
pub struct SetSeq<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetSeq<S> {}
impl<S: State> State for SetSeq<S> {
type HoldEndpoint = S::HoldEndpoint;
type HoldDid = S::HoldDid;
type Type = S::Type;
type Digest = S::Digest;
type Seq = Set<members::seq>;
type UserDid = S::UserDid;
type Repository = S::Repository;
}
pub struct SetUserDid<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetUserDid<S> {}
impl<S: State> State for SetUserDid<S> {
type HoldEndpoint = S::HoldEndpoint;
type HoldDid = S::HoldDid;
type Type = S::Type;
type Digest = S::Digest;
type Seq = S::Seq;
type UserDid = Set<members::user_did>;
type Repository = S::Repository;
}
pub struct SetRepository<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetRepository<S> {}
impl<S: State> State for SetRepository<S> {
type HoldEndpoint = S::HoldEndpoint;
type HoldDid = S::HoldDid;
type Type = S::Type;
type Digest = S::Digest;
type Seq = S::Seq;
type UserDid = S::UserDid;
type Repository = Set<members::repository>;
}
#[allow(non_camel_case_types)]
pub mod members {
pub struct hold_endpoint(());
pub struct hold_did(());
pub struct r#type(());
pub struct digest(());
pub struct seq(());
pub struct user_did(());
pub struct repository(());
}
}
pub struct ScanJobBuilder<'a, S: scan_job_state::State> {
_state: PhantomData<fn() -> S>,
_fields: (
Option<CowStr<'a>>,
Option<Did<'a>>,
Option<UriValue<'a>>,
Option<i64>,
Option<CowStr<'a>>,
Option<i64>,
Option<CowStr<'a>>,
Option<CowStr<'a>>,
Option<Did<'a>>,
),
_lifetime: PhantomData<&'a ()>,
}
impl<'a> ScanJob<'a> {
pub fn new() -> ScanJobBuilder<'a, scan_job_state::Empty> {
ScanJobBuilder::new()
}
}
impl<'a> ScanJobBuilder<'a, scan_job_state::Empty> {
pub fn new() -> Self {
ScanJobBuilder {
_state: PhantomData,
_fields: (None, None, None, None, None, None, None, None, None),
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::Digest: scan_job_state::IsUnset,
{
pub fn digest(
mut self,
value: impl Into<CowStr<'a>>,
) -> ScanJobBuilder<'a, scan_job_state::SetDigest<S>> {
self._fields.0 = Option::Some(value.into());
ScanJobBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::HoldDid: scan_job_state::IsUnset,
{
pub fn hold_did(
mut self,
value: impl Into<Did<'a>>,
) -> ScanJobBuilder<'a, scan_job_state::SetHoldDid<S>> {
self._fields.1 = Option::Some(value.into());
ScanJobBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::HoldEndpoint: scan_job_state::IsUnset,
{
pub fn hold_endpoint(
mut self,
value: impl Into<UriValue<'a>>,
) -> ScanJobBuilder<'a, scan_job_state::SetHoldEndpoint<S>> {
self._fields.2 = Option::Some(value.into());
ScanJobBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S: scan_job_state::State> ScanJobBuilder<'a, S> {
pub fn priority(mut self, value: impl Into<Option<i64>>) -> Self {
self._fields.3 = value.into();
self
}
pub fn maybe_priority(mut self, value: Option<i64>) -> Self {
self._fields.3 = value;
self
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::Repository: scan_job_state::IsUnset,
{
pub fn repository(
mut self,
value: impl Into<CowStr<'a>>,
) -> ScanJobBuilder<'a, scan_job_state::SetRepository<S>> {
self._fields.4 = Option::Some(value.into());
ScanJobBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::Seq: scan_job_state::IsUnset,
{
pub fn seq(
mut self,
value: impl Into<i64>,
) -> ScanJobBuilder<'a, scan_job_state::SetSeq<S>> {
self._fields.5 = Option::Some(value.into());
ScanJobBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S: scan_job_state::State> ScanJobBuilder<'a, S> {
pub fn tag(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
self._fields.6 = value.into();
self
}
pub fn maybe_tag(mut self, value: Option<CowStr<'a>>) -> Self {
self._fields.6 = value;
self
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::Type: scan_job_state::IsUnset,
{
pub fn r#type(
mut self,
value: impl Into<CowStr<'a>>,
) -> ScanJobBuilder<'a, scan_job_state::SetType<S>> {
self._fields.7 = Option::Some(value.into());
ScanJobBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::UserDid: scan_job_state::IsUnset,
{
pub fn user_did(
mut self,
value: impl Into<Did<'a>>,
) -> ScanJobBuilder<'a, scan_job_state::SetUserDid<S>> {
self._fields.8 = Option::Some(value.into());
ScanJobBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanJobBuilder<'a, S>
where
S: scan_job_state::State,
S::HoldEndpoint: scan_job_state::IsSet,
S::HoldDid: scan_job_state::IsSet,
S::Type: scan_job_state::IsSet,
S::Digest: scan_job_state::IsSet,
S::Seq: scan_job_state::IsSet,
S::UserDid: scan_job_state::IsSet,
S::Repository: scan_job_state::IsSet,
{
pub fn build(self) -> ScanJob<'a> {
ScanJob {
digest: self._fields.0.unwrap(),
hold_did: self._fields.1.unwrap(),
hold_endpoint: self._fields.2.unwrap(),
priority: self._fields.3,
repository: self._fields.4.unwrap(),
seq: self._fields.5.unwrap(),
tag: self._fields.6,
r#type: self._fields.7.unwrap(),
user_did: self._fields.8.unwrap(),
extra_data: Default::default(),
}
}
pub fn build_with_data(
self,
extra_data: BTreeMap<
jacquard_common::deps::smol_str::SmolStr,
jacquard_common::types::value::Data<'a>,
>,
) -> ScanJob<'a> {
ScanJob {
digest: self._fields.0.unwrap(),
hold_did: self._fields.1.unwrap(),
hold_endpoint: self._fields.2.unwrap(),
priority: self._fields.3,
repository: self._fields.4.unwrap(),
seq: self._fields.5.unwrap(),
tag: self._fields.6,
r#type: self._fields.7.unwrap(),
user_did: self._fields.8.unwrap(),
extra_data: Some(extra_data),
}
}
}
fn lexicon_doc_io_atcr_hold_subscribeScanJobs() -> LexiconDoc<'static> {
#[allow(unused_imports)]
use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
use jacquard_lexicon::lexicon::*;
use alloc::collections::BTreeMap;
LexiconDoc {
lexicon: Lexicon::Lexicon1,
id: CowStr::new_static("io.atcr.hold.subscribeScanJobs"),
defs: {
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("main"),
LexUserType::XrpcSubscription(LexXrpcSubscription {
parameters: Some(
LexXrpcSubscriptionParameter::Params(LexXrpcParameters {
properties: {
#[allow(unused_mut)]
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("cursor"),
LexXrpcParametersProperty::Integer(LexInteger {
..Default::default()
}),
);
map
},
..Default::default()
}),
),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("scanJob"),
LexUserType::Object(LexObject {
description: Some(
CowStr::new_static(
"A scan job dispatched from hold to scanner. Sent as a JSON WebSocket message.",
),
),
required: Some(
vec![
SmolStr::new_static("type"), SmolStr::new_static("seq"),
SmolStr::new_static("digest"),
SmolStr::new_static("repository"),
SmolStr::new_static("userDid"),
SmolStr::new_static("holdDid"),
SmolStr::new_static("holdEndpoint")
],
),
properties: {
#[allow(unused_mut)]
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("digest"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"Manifest digest (e.g., sha256:abc123...)",
),
),
max_length: Some(128usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("holdDid"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"DID of the hold where the image is stored",
),
),
format: Some(LexStringFormat::Did),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("holdEndpoint"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static(
"HTTP endpoint of the hold for blob downloads",
),
),
format: Some(LexStringFormat::Uri),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("priority"),
LexObjectProperty::Integer(LexInteger {
..Default::default()
}),
);
map.insert(
SmolStr::new_static("repository"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("Repository name (e.g., myapp)"),
),
max_length: Some(256usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("seq"),
LexObjectProperty::Integer(LexInteger {
..Default::default()
}),
);
map.insert(
SmolStr::new_static("tag"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("Optional tag that triggered the scan"),
),
max_length: Some(256usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("type"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("Message type discriminator"),
),
max_length: Some(32usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("userDid"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("DID of the image owner"),
),
format: Some(LexStringFormat::Did),
..Default::default()
}),
);
map
},
..Default::default()
}),
);
map.insert(
SmolStr::new_static("scanResult"),
LexUserType::Object(LexObject {
description: Some(
CowStr::new_static(
"A scan result sent from scanner back to hold. Sent as a JSON WebSocket message.",
),
),
required: Some(
vec![
SmolStr::new_static("type"), SmolStr::new_static("digest"),
SmolStr::new_static("summary")
],
),
properties: {
#[allow(unused_mut)]
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("digest"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("Manifest digest that was scanned"),
),
max_length: Some(128usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("error"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("Error message if scan failed"),
),
max_length: Some(1024usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("sbom"),
LexObjectProperty::Bytes(LexBytes {
max_length: Some(104857600usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("scannerVersion"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("Scanner version string"),
),
max_length: Some(64usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("summary"),
LexObjectProperty::Ref(LexRef {
r#ref: CowStr::new_static("#vulnSummary"),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("type"),
LexObjectProperty::String(LexString {
description: Some(
CowStr::new_static("Message type discriminator"),
),
max_length: Some(32usize),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("vulnReport"),
LexObjectProperty::Bytes(LexBytes {
max_length: Some(104857600usize),
..Default::default()
}),
);
map
},
..Default::default()
}),
);
map.insert(
SmolStr::new_static("vulnSummary"),
LexUserType::Object(LexObject {
required: Some(
vec![
SmolStr::new_static("critical"), SmolStr::new_static("high"),
SmolStr::new_static("medium"), SmolStr::new_static("low"),
SmolStr::new_static("total")
],
),
properties: {
#[allow(unused_mut)]
let mut map = BTreeMap::new();
map.insert(
SmolStr::new_static("critical"),
LexObjectProperty::Integer(LexInteger {
minimum: Some(0i64),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("high"),
LexObjectProperty::Integer(LexInteger {
minimum: Some(0i64),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("low"),
LexObjectProperty::Integer(LexInteger {
minimum: Some(0i64),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("medium"),
LexObjectProperty::Integer(LexInteger {
minimum: Some(0i64),
..Default::default()
}),
);
map.insert(
SmolStr::new_static("total"),
LexObjectProperty::Integer(LexInteger {
minimum: Some(0i64),
..Default::default()
}),
);
map
},
..Default::default()
}),
);
map
},
..Default::default()
}
}
pub mod scan_result_state {
pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
#[allow(unused)]
use ::core::marker::PhantomData;
mod sealed {
pub trait Sealed {}
}
pub trait State: sealed::Sealed {
type Type;
type Digest;
type Summary;
}
pub struct Empty(());
impl sealed::Sealed for Empty {}
impl State for Empty {
type Type = Unset;
type Digest = Unset;
type Summary = Unset;
}
pub struct SetType<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetType<S> {}
impl<S: State> State for SetType<S> {
type Type = Set<members::r#type>;
type Digest = S::Digest;
type Summary = S::Summary;
}
pub struct SetDigest<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetDigest<S> {}
impl<S: State> State for SetDigest<S> {
type Type = S::Type;
type Digest = Set<members::digest>;
type Summary = S::Summary;
}
pub struct SetSummary<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetSummary<S> {}
impl<S: State> State for SetSummary<S> {
type Type = S::Type;
type Digest = S::Digest;
type Summary = Set<members::summary>;
}
#[allow(non_camel_case_types)]
pub mod members {
pub struct r#type(());
pub struct digest(());
pub struct summary(());
}
}
pub struct ScanResultBuilder<'a, S: scan_result_state::State> {
_state: PhantomData<fn() -> S>,
_fields: (
Option<CowStr<'a>>,
Option<CowStr<'a>>,
Option<Bytes>,
Option<CowStr<'a>>,
Option<subscribe_scan_jobs::VulnSummary<'a>>,
Option<CowStr<'a>>,
Option<Bytes>,
),
_lifetime: PhantomData<&'a ()>,
}
impl<'a> ScanResult<'a> {
pub fn new() -> ScanResultBuilder<'a, scan_result_state::Empty> {
ScanResultBuilder::new()
}
}
impl<'a> ScanResultBuilder<'a, scan_result_state::Empty> {
pub fn new() -> Self {
ScanResultBuilder {
_state: PhantomData,
_fields: (None, None, None, None, None, None, None),
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanResultBuilder<'a, S>
where
S: scan_result_state::State,
S::Digest: scan_result_state::IsUnset,
{
pub fn digest(
mut self,
value: impl Into<CowStr<'a>>,
) -> ScanResultBuilder<'a, scan_result_state::SetDigest<S>> {
self._fields.0 = Option::Some(value.into());
ScanResultBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S: scan_result_state::State> ScanResultBuilder<'a, S> {
pub fn error(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
self._fields.1 = value.into();
self
}
pub fn maybe_error(mut self, value: Option<CowStr<'a>>) -> Self {
self._fields.1 = value;
self
}
}
impl<'a, S: scan_result_state::State> ScanResultBuilder<'a, S> {
pub fn sbom(mut self, value: impl Into<Option<Bytes>>) -> Self {
self._fields.2 = value.into();
self
}
pub fn maybe_sbom(mut self, value: Option<Bytes>) -> Self {
self._fields.2 = value;
self
}
}
impl<'a, S: scan_result_state::State> ScanResultBuilder<'a, S> {
pub fn scanner_version(mut self, value: impl Into<Option<CowStr<'a>>>) -> Self {
self._fields.3 = value.into();
self
}
pub fn maybe_scanner_version(mut self, value: Option<CowStr<'a>>) -> Self {
self._fields.3 = value;
self
}
}
impl<'a, S> ScanResultBuilder<'a, S>
where
S: scan_result_state::State,
S::Summary: scan_result_state::IsUnset,
{
pub fn summary(
mut self,
value: impl Into<subscribe_scan_jobs::VulnSummary<'a>>,
) -> ScanResultBuilder<'a, scan_result_state::SetSummary<S>> {
self._fields.4 = Option::Some(value.into());
ScanResultBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> ScanResultBuilder<'a, S>
where
S: scan_result_state::State,
S::Type: scan_result_state::IsUnset,
{
pub fn r#type(
mut self,
value: impl Into<CowStr<'a>>,
) -> ScanResultBuilder<'a, scan_result_state::SetType<S>> {
self._fields.5 = Option::Some(value.into());
ScanResultBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S: scan_result_state::State> ScanResultBuilder<'a, S> {
pub fn vuln_report(mut self, value: impl Into<Option<Bytes>>) -> Self {
self._fields.6 = value.into();
self
}
pub fn maybe_vuln_report(mut self, value: Option<Bytes>) -> Self {
self._fields.6 = value;
self
}
}
impl<'a, S> ScanResultBuilder<'a, S>
where
S: scan_result_state::State,
S::Type: scan_result_state::IsSet,
S::Digest: scan_result_state::IsSet,
S::Summary: scan_result_state::IsSet,
{
pub fn build(self) -> ScanResult<'a> {
ScanResult {
digest: self._fields.0.unwrap(),
error: self._fields.1,
sbom: self._fields.2,
scanner_version: self._fields.3,
summary: self._fields.4.unwrap(),
r#type: self._fields.5.unwrap(),
vuln_report: self._fields.6,
extra_data: Default::default(),
}
}
pub fn build_with_data(
self,
extra_data: BTreeMap<
jacquard_common::deps::smol_str::SmolStr,
jacquard_common::types::value::Data<'a>,
>,
) -> ScanResult<'a> {
ScanResult {
digest: self._fields.0.unwrap(),
error: self._fields.1,
sbom: self._fields.2,
scanner_version: self._fields.3,
summary: self._fields.4.unwrap(),
r#type: self._fields.5.unwrap(),
vuln_report: self._fields.6,
extra_data: Some(extra_data),
}
}
}
pub mod vuln_summary_state {
pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
#[allow(unused)]
use ::core::marker::PhantomData;
mod sealed {
pub trait Sealed {}
}
pub trait State: sealed::Sealed {
type Medium;
type Low;
type High;
type Total;
type Critical;
}
pub struct Empty(());
impl sealed::Sealed for Empty {}
impl State for Empty {
type Medium = Unset;
type Low = Unset;
type High = Unset;
type Total = Unset;
type Critical = Unset;
}
pub struct SetMedium<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetMedium<S> {}
impl<S: State> State for SetMedium<S> {
type Medium = Set<members::medium>;
type Low = S::Low;
type High = S::High;
type Total = S::Total;
type Critical = S::Critical;
}
pub struct SetLow<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetLow<S> {}
impl<S: State> State for SetLow<S> {
type Medium = S::Medium;
type Low = Set<members::low>;
type High = S::High;
type Total = S::Total;
type Critical = S::Critical;
}
pub struct SetHigh<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetHigh<S> {}
impl<S: State> State for SetHigh<S> {
type Medium = S::Medium;
type Low = S::Low;
type High = Set<members::high>;
type Total = S::Total;
type Critical = S::Critical;
}
pub struct SetTotal<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetTotal<S> {}
impl<S: State> State for SetTotal<S> {
type Medium = S::Medium;
type Low = S::Low;
type High = S::High;
type Total = Set<members::total>;
type Critical = S::Critical;
}
pub struct SetCritical<S: State = Empty>(PhantomData<fn() -> S>);
impl<S: State> sealed::Sealed for SetCritical<S> {}
impl<S: State> State for SetCritical<S> {
type Medium = S::Medium;
type Low = S::Low;
type High = S::High;
type Total = S::Total;
type Critical = Set<members::critical>;
}
#[allow(non_camel_case_types)]
pub mod members {
pub struct medium(());
pub struct low(());
pub struct high(());
pub struct total(());
pub struct critical(());
}
}
pub struct VulnSummaryBuilder<'a, S: vuln_summary_state::State> {
_state: PhantomData<fn() -> S>,
_fields: (Option<i64>, Option<i64>, Option<i64>, Option<i64>, Option<i64>),
_lifetime: PhantomData<&'a ()>,
}
impl<'a> VulnSummary<'a> {
pub fn new() -> VulnSummaryBuilder<'a, vuln_summary_state::Empty> {
VulnSummaryBuilder::new()
}
}
impl<'a> VulnSummaryBuilder<'a, vuln_summary_state::Empty> {
pub fn new() -> Self {
VulnSummaryBuilder {
_state: PhantomData,
_fields: (None, None, None, None, None),
_lifetime: PhantomData,
}
}
}
impl<'a, S> VulnSummaryBuilder<'a, S>
where
S: vuln_summary_state::State,
S::Critical: vuln_summary_state::IsUnset,
{
pub fn critical(
mut self,
value: impl Into<i64>,
) -> VulnSummaryBuilder<'a, vuln_summary_state::SetCritical<S>> {
self._fields.0 = Option::Some(value.into());
VulnSummaryBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> VulnSummaryBuilder<'a, S>
where
S: vuln_summary_state::State,
S::High: vuln_summary_state::IsUnset,
{
pub fn high(
mut self,
value: impl Into<i64>,
) -> VulnSummaryBuilder<'a, vuln_summary_state::SetHigh<S>> {
self._fields.1 = Option::Some(value.into());
VulnSummaryBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> VulnSummaryBuilder<'a, S>
where
S: vuln_summary_state::State,
S::Low: vuln_summary_state::IsUnset,
{
pub fn low(
mut self,
value: impl Into<i64>,
) -> VulnSummaryBuilder<'a, vuln_summary_state::SetLow<S>> {
self._fields.2 = Option::Some(value.into());
VulnSummaryBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> VulnSummaryBuilder<'a, S>
where
S: vuln_summary_state::State,
S::Medium: vuln_summary_state::IsUnset,
{
pub fn medium(
mut self,
value: impl Into<i64>,
) -> VulnSummaryBuilder<'a, vuln_summary_state::SetMedium<S>> {
self._fields.3 = Option::Some(value.into());
VulnSummaryBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> VulnSummaryBuilder<'a, S>
where
S: vuln_summary_state::State,
S::Total: vuln_summary_state::IsUnset,
{
pub fn total(
mut self,
value: impl Into<i64>,
) -> VulnSummaryBuilder<'a, vuln_summary_state::SetTotal<S>> {
self._fields.4 = Option::Some(value.into());
VulnSummaryBuilder {
_state: PhantomData,
_fields: self._fields,
_lifetime: PhantomData,
}
}
}
impl<'a, S> VulnSummaryBuilder<'a, S>
where
S: vuln_summary_state::State,
S::Medium: vuln_summary_state::IsSet,
S::Low: vuln_summary_state::IsSet,
S::High: vuln_summary_state::IsSet,
S::Total: vuln_summary_state::IsSet,
S::Critical: vuln_summary_state::IsSet,
{
pub fn build(self) -> VulnSummary<'a> {
VulnSummary {
critical: self._fields.0.unwrap(),
high: self._fields.1.unwrap(),
low: self._fields.2.unwrap(),
medium: self._fields.3.unwrap(),
total: self._fields.4.unwrap(),
extra_data: Default::default(),
}
}
pub fn build_with_data(
self,
extra_data: BTreeMap<
jacquard_common::deps::smol_str::SmolStr,
jacquard_common::types::value::Data<'a>,
>,
) -> VulnSummary<'a> {
VulnSummary {
critical: self._fields.0.unwrap(),
high: self._fields.1.unwrap(),
low: self._fields.2.unwrap(),
medium: self._fields.3.unwrap(),
total: self._fields.4.unwrap(),
extra_data: Some(extra_data),
}
}
}