Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename bitstream_status_list module into bitstring_status_list. #573

Merged
merged 6 commits into from
Jul 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions crates/status/examples/status_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use ssi_data_integrity::{AnySuite, ProofOptions};
use ssi_dids::{VerificationMethodDIDResolver, DIDJWK};
use ssi_jwk::JWK;
use ssi_status::{
any::AnyStatusMap, bitstream_status_list, EncodedStatusMap, FromBytes, FromBytesOptions,
any::AnyStatusMap, bitstring_status_list, EncodedStatusMap, FromBytes, FromBytesOptions,
};
use ssi_verification_methods::{ReferenceOrOwned, SingleSecretSigner};
use std::{
Expand Down Expand Up @@ -139,34 +139,34 @@ impl Command {
Ok(())
}
Self::Create { id, list, key } => {
let data = create_bitstream_status_list(id.clone(), list, key).await?;
let data = create_bitstring_status_list(id.clone(), list, key).await?;
stdout().write_all(&data).unwrap();
Ok(())
}
}
}
}

async fn create_bitstream_status_list(
async fn create_bitstring_status_list(
id: UriBuf,
list: Vec<StatusValue>,
key: Option<PathBuf>,
) -> Result<Vec<u8>, Error> {
let mut status_list = bitstream_status_list::StatusList::new(
bitstream_status_list::StatusSize::default(),
bitstream_status_list::TimeToLive::default(),
let mut status_list = bitstring_status_list::StatusList::new(
bitstring_status_list::StatusSize::default(),
bitstring_status_list::TimeToLive::default(),
// list.into_iter().map(|v| v.0).collect(),
);

for v in list {
status_list.push(v.0).unwrap();
}

let credential = bitstream_status_list::BitstringStatusListCredential::new(
let credential = bitstring_status_list::BitstringStatusListCredential::new(
Some(id),
status_list.to_credential_subject(
None,
bitstream_status_list::StatusPurpose::Revocation,
bitstring_status_list::StatusPurpose::Revocation,
Vec::new(),
),
);
Expand Down
14 changes: 7 additions & 7 deletions crates/status/src/impl/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ssi_jwk::JWKResolver;
use ssi_verification_methods::{AnyMethod, VerificationMethodResolver};

use crate::{
bitstream_status_list::{
bitstring_status_list::{
self, BitstringStatusListCredential, BitstringStatusListEntry,
BitstringStatusListEntrySetCredential,
},
Expand Down Expand Up @@ -34,7 +34,7 @@ pub enum FromBytesError {
UnexpectedMediaType(String),

#[error(transparent)]
BitstringStatusList(bitstream_status_list::FromBytesError),
BitstringStatusList(bitstring_status_list::FromBytesError),

#[error(transparent)]
TokenStatusList(token_status_list::FromBytesError),
Expand Down Expand Up @@ -77,7 +77,7 @@ where
#[derive(Debug, thiserror::Error)]
pub enum DecodeError {
#[error(transparent)]
BitstringStatusList(#[from] bitstream_status_list::DecodeError),
BitstringStatusList(#[from] bitstring_status_list::DecodeError),

#[error(transparent)]
TokenStatusList(#[from] token_status_list::DecodeError),
Expand All @@ -103,7 +103,7 @@ impl EncodedStatusMap for AnyStatusMap {

#[derive(Clone)]
pub enum AnyDecodedStatusMap {
BitstringStatusList(bitstream_status_list::StatusList),
BitstringStatusList(bitstring_status_list::StatusList),
TokenStatusList(token_status_list::StatusList),
}

Expand Down Expand Up @@ -145,7 +145,7 @@ impl<'a> IntoIterator for &'a AnyDecodedStatusMap {
}

pub enum AnyDecodedStatusMapIter<'a> {
BitstringStatusList(bitstream_status_list::BitStringIter<'a>),
BitstringStatusList(bitstring_status_list::BitStringIter<'a>),
TokenStatusList(token_status_list::BitStringIter<'a>),
}

Expand All @@ -166,7 +166,7 @@ pub enum EntrySetFromBytesError {
TokenStatusList(#[from] token_status_list::EntrySetFromBytesError),

#[error(transparent)]
BitstringStatusList(#[from] bitstream_status_list::FromBytesError),
BitstringStatusList(#[from] bitstring_status_list::FromBytesError),

#[error("unexpected media type `{0}`")]
UnexpectedMediaType(String),
Expand Down Expand Up @@ -203,7 +203,7 @@ where
| "application/vc+ld+json+sd-jwt"
| "application/vc+ld+json+cose"
| "application/vc+ld+json" => {
bitstream_status_list::BitstringStatusListEntrySetCredential::from_bytes_with(
bitstring_status_list::BitstringStatusListEntrySetCredential::from_bytes_with(
bytes, media_type, params, options,
)
.await
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
//! Credentials through use of bitstrings.
//!
//! See: <https://www.w3.org/TR/vc-bitstring-status-list/>
use core::fmt;
use iref::UriBuf;
use serde::{Deserialize, Serialize};
use std::{hash::Hash, time::Duration};
use std::{hash::Hash, str::FromStr, time::Duration};

use crate::{Overflow, StatusMap};

Expand Down Expand Up @@ -127,7 +128,7 @@ impl From<TimeToLive> for Duration {
}
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum StatusPurpose {
/// Cancel the validity of a verifiable credential.
Expand All @@ -142,9 +143,54 @@ pub enum StatusPurpose {

/// Convey an arbitrary message related to the status of the verifiable
/// credential.
///
/// The actual message is stored in the status list credential, in
/// [`BitstringStatusList::status_message`].
Message,
}

impl StatusPurpose {
/// Creates a new status purpose from its name.
pub fn from_name(name: &str) -> Option<Self> {
match name {
"revocation" => Some(Self::Revocation),
"suspension" => Some(Self::Suspension),
"message" => Some(Self::Message),
_ => None,
}
}

/// Returns the name of this status purpose.
pub fn name(&self) -> &'static str {
match self {
Self::Revocation => "revocation",
Self::Suspension => "suspension",
Self::Message => "message",
}
}

/// Returns the string representation of this status purpose.
///
/// Same as [`Self::name`].
pub fn as_str(&self) -> &'static str {
self.name()
}

/// Turns this status purpose into its name.
///
/// Same as [`Self::name`].
pub fn into_name(self) -> &'static str {
self.name()
}

/// Turns this status purpose into its string representation.
///
/// Same as [`Self::name`].
pub fn into_str(self) -> &'static str {
self.name()
}
}

impl<'a> From<&'a StatusPurpose> for crate::StatusPurpose<&'a str> {
fn from(value: &'a StatusPurpose) -> Self {
match value {
Expand All @@ -166,6 +212,25 @@ impl<'a> PartialEq<crate::StatusPurpose<&'a str>> for StatusPurpose {
}
}

impl fmt::Display for StatusPurpose {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.name().fmt(f)
}
}

/// Error raised when converting a string into a [`StatusPurpose`] fails.
#[derive(Debug, Clone, thiserror::Error)]
#[error("invalid status purpose: {0}")]
pub struct InvalidStatusPurpose(pub String);

impl FromStr for StatusPurpose {
type Err = InvalidStatusPurpose;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::from_name(s).ok_or_else(|| InvalidStatusPurpose(s.to_owned()))
}
}

/// Bit-string as defined by the W3C Bitstring Status List specification.
///
/// Bits are indexed from most significant to least significant.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use ssi_vc::v2::{syntax::JsonCredentialTypes, Context};
use ssi_verification_methods::{ssi_core::OneOrMany, AnyMethod, VerificationMethodResolver};

use crate::{
bitstream_status_list::FromBytesError, FromBytes, FromBytesOptions, StatusMapEntrySet,
bitstring_status_list::FromBytesError, FromBytes, FromBytesOptions, StatusMapEntrySet,
};

use super::BitstringStatusListEntry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
mod credential;
pub use credential::*;

use crate::{bitstream_status_list::StatusPurpose, StatusMapEntry};
use crate::{bitstring_status_list::StatusPurpose, StatusMapEntry};

pub const BITSTRING_STATUS_LIST_ENTRY_TYPE: &str = "BitstringStatusListEntry";

Expand All @@ -16,28 +16,41 @@ pub const BITSTRING_STATUS_LIST_ENTRY_TYPE: &str = "BitstringStatusListEntry";
///
/// See: <https://www.w3.org/TR/vc-bitstring-status-list/#bitstringstatuslistentry>
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type", rename_all = "camelCase")]
pub struct BitstringStatusListEntry {
/// Optional identifier for the status list entry.
///
/// Identifies the status information associated with the verifiable
/// credential. Must *not* be the URL of the status list.
id: Option<UriBuf>,

/// `BitstringStatusListEntry` type.
#[serde(rename = "type")]
type_: BitstringStatusListEntryType,
pub id: Option<UriBuf>,

/// Purpose of the status entry.
status_purpose: StatusPurpose,
pub status_purpose: StatusPurpose,

/// URL to a `BitstringStatusListCredential` verifiable credential.
status_list_credential: UriBuf,
pub status_list_credential: UriBuf,

/// Arbitrary size integer greater than or equal to 0, encoded as a string
/// in base 10.
#[serde(with = "base10_nat_string")]
status_list_index: usize,
pub status_list_index: usize,
}

impl BitstringStatusListEntry {
/// Creates a new bit-string status list entry.
pub fn new(
id: Option<UriBuf>,
status_purpose: StatusPurpose,
status_list_credential: UriBuf,
status_list_index: usize,
) -> Self {
Self {
id,
status_purpose,
status_list_credential,
status_list_index,
}
}
}

impl StatusMapEntry for BitstringStatusListEntry {
Expand All @@ -52,34 +65,6 @@ impl StatusMapEntry for BitstringStatusListEntry {
}
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BitstringStatusListEntryType;

impl Serialize for BitstringStatusListEntryType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
BITSTRING_STATUS_LIST_ENTRY_TYPE.serialize(serializer)
}
}

impl<'de> Deserialize<'de> for BitstringStatusListEntryType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let type_ = String::deserialize(deserializer)?;
if type_ == BITSTRING_STATUS_LIST_ENTRY_TYPE {
Ok(Self)
} else {
Err(serde::de::Error::custom(
"expected `BitstringStatusListEntry` type",
))
}
}
}

mod base10_nat_string {
use serde::{Deserialize, Deserializer, Serialize, Serializer};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@ use serde::{Deserialize, Serialize};
mod credential;
pub use credential::*;

use crate::bitstream_status_list::{
use crate::bitstring_status_list::{
EncodedList, StatusList, StatusMessage, StatusPurpose, StatusSize, TimeToLive,
};

pub const BITSTRING_STATUS_LIST_TYPE: &str = "BitstringStatusList";

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type", rename_all = "camelCase")]
pub struct BitstringStatusList {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<UriBuf>,

/// `BitstringStatusList` type.
#[serde(rename = "type")]
pub type_: BitstringStatusListType,

/// Status purpose.
pub status_purpose: StatusPurpose,

Expand Down Expand Up @@ -52,7 +48,6 @@ impl BitstringStatusList {
) -> Self {
Self {
id,
type_: BitstringStatusListType,
status_purpose,
status_size,
encoded_list,
Expand All @@ -67,31 +62,3 @@ impl BitstringStatusList {
Ok(StatusList::from_bytes(self.status_size, bytes, self.ttl))
}
}

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BitstringStatusListType;

impl Serialize for BitstringStatusListType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
BITSTRING_STATUS_LIST_TYPE.serialize(serializer)
}
}

impl<'de> Deserialize<'de> for BitstringStatusListType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let type_ = String::deserialize(deserializer)?;
if type_ == BITSTRING_STATUS_LIST_TYPE {
Ok(Self)
} else {
Err(serde::de::Error::custom(
"expected `BitstringStatusList` type",
))
}
}
}
2 changes: 1 addition & 1 deletion crates/status/src/impl/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod any;
pub mod bitstream_status_list;
pub mod bitstring_status_list;
pub mod token_status_list;

pub use flate2::Compression;
Expand Down