1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! # Binary object storage and streaming
//!
//! This module contains data types for the `wascc:blobstore` capability provider. For more information on
//! how the blob store capability works within the constraints of a WebAssembly host runtime, check out
//! the documentation on [waSCC.dev](https://wascc.dev)

use crate::Sample;

/// Guest sends a Container to the capability provider, receives a Container back
pub const OP_CREATE_CONTAINER: &str = "CreateContainer";
/// Guest sends a Container to the capability provider, lack of error indicates success
pub const OP_REMOVE_CONTAINER: &str = "RemoveContainer";
/// Guest sends a Blob to the capability provider, lack of error indicates success
pub const OP_REMOVE_OBJECT: &str = "RemoveObject";
/// Guest sends a Container to the capability provider, receives a BlobList back
pub const OP_LIST_OBJECTS: &str = "ListObjects";
/// Guest sends a FileChunk to capability provider for storing as part of a Blob, lack of error indicates success
pub const OP_UPLOAD_CHUNK: &str = "UploadChunk";
/// Guest sends a StreamRequest to the capability provider, immediate termination w/success. Guest will then
/// start receiving OP_RECEIVE_CHUNK operations from the provider as chunks are streamed to the guest
pub const OP_START_DOWNLOAD: &str = "StartDownload";
/// Guest sends a metadata-carrying FileChunk to initiate an upload, lack of error is success
pub const OP_START_UPLOAD: &str = "StartUpload";
/// Guest will receive a FileChunk for each piece of a file requested to download
pub const OP_RECEIVE_CHUNK: &str = "ReceiveChunk";
/// Query information on a single blob. Guest sends an incomplete blob struct and gets a complete one in return
pub const OP_GET_OBJECT_INFO: &str = "GetObjectInfo";

/// Represents a single chunk of a segmented file stream
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct FileChunk {
    /// A sequence number that can be used for retry and ordering logic
    pub sequence_no: u64,
    /// The container in which this file exists
    pub container: String,
    /// The unique ID of the blob
    pub id: String,
    /// Total number of bytes in the entire blob
    pub total_bytes: u64,
    /// The number of bytes within any given chunk. Note that the last chunk in a file stream may be less than `chunk_size`
    pub chunk_size: u64,
    /// The raw bytes contained in this chunk
    #[serde(with = "serde_bytes")]
    #[serde(default)]
    pub chunk_bytes: Vec<u8>,
}

impl Sample for FileChunk {
    fn sample() -> Self {
        FileChunk {
            sequence_no: 5,
            container: "container".to_string(),
            id: "blob".to_string(),
            total_bytes: 53400,
            chunk_size: 1024,
            chunk_bytes: vec![1, 2, 3, 4, 5],
        }
    }
}

/// Represents a container within a blob store
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Container {
    pub id: String,
}

/// Used to hold a list of containers
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ContainerList {
    #[serde(default)]
    pub containers: Vec<Container>,
}

impl Sample for ContainerList {
    fn sample() -> Self {
        ContainerList {
            containers: vec![Container {
                id: "container".to_string(),
            }],
        }
    }
}

/// Metadata about a blob, not the raw bytes
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Blob {
    /// Unique ID of the blob
    pub id: String,
    /// Container in which the blob resides
    pub container: String,
    /// Total number of bytes of the blob (file size)
    pub byte_size: u64,
}

/// A wrapper for a list of blobs
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BlobList {
    #[serde(default)]
    pub blobs: Vec<Blob>,
}

/// A request to begin downloading a stream for a blob
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StreamRequest {
    /// The unique ID of the requested blob
    pub id: String,
    /// The container of the requested blob
    pub container: String,
    /// The preferred size of chunks to be delivered. Consumers must not assume this is the size of the chunks they will get
    pub chunk_size: u64,
}

/// Metadata about an in-progress file transfer
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Transfer {
    /// Unique ID of the blob
    pub blob_id: String,
    /// ID of the container
    pub container: String,
    /// Size of chunks being transferred
    pub chunk_size: u64,
    /// Total number of bytes being transferred
    pub total_size: u64,
    /// Total number of chunks being transferred
    pub total_chunks: u64,
}