Skip to content

Commit

Permalink
🚀 Kick start slot package
Browse files Browse the repository at this point in the history
  • Loading branch information
bal7hazar committed Nov 14, 2024
1 parent 5de432c commit 7eb097b
Show file tree
Hide file tree
Showing 12 changed files with 597 additions and 1 deletion.
8 changes: 8 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ dependencies = [
"dojo_cairo_test",
]

[[package]]
name = "arcade_slot"
version = "0.0.0"
dependencies = [
"dojo",
"dojo_cairo_test",
]

[[package]]
name = "arcade_trophy"
version = "0.0.0"
Expand Down
2 changes: 1 addition & 1 deletion Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["packages/trophy", "packages/registry"]
members = ["packages/trophy", "packages/registry", "packages/slot"]
description = "Dojo achievement library"
homepage = "https://github.com/cartridge-gg/arcade/"
cairo-version = "2.8.4"
Expand Down
Empty file added packages/slot/README.md
Empty file.
9 changes: 9 additions & 0 deletions packages/slot/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "arcade_slot"
version.workspace = true

[dependencies]
dojo.workspace = true

[dev-dependencies]
dojo_cairo_test.workspace = true
1 change: 1 addition & 0 deletions packages/slot/src/constants.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

172 changes: 172 additions & 0 deletions packages/slot/src/helpers/json.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
//! JSON helper functions

pub trait JsonableTrait<T> {
fn jsonify(self: T) -> ByteArray;
}

pub impl Jsonable<T, +Drop<T>, +core::fmt::Display<T>> of JsonableTrait<T> {
fn jsonify(self: T) -> ByteArray {
format!("{}", self)
}
}

#[generate_trait]
pub impl JsonableSimple of JsonableSimpleTrait {
fn jsonify(name: ByteArray, value: ByteArray) -> ByteArray {
format!("\"{}\":{}", name, value)
}
}

#[generate_trait]
pub impl JsonableString of JsonableStringTrait {
fn jsonify(name: ByteArray, value: ByteArray) -> ByteArray {
format!("\"{}\":\"{}\"", name, value)
}
}

#[generate_trait]
pub impl JsonableArray<T, +JsonableTrait<T>, +Drop<T>> of JsonableArrayTrait<T> {
fn jsonify(name: ByteArray, mut value: Array<T>) -> ByteArray {
let mut string = "[";
let mut index: u32 = 0;
while let Option::Some(item) = value.pop_front() {
if index > 0 {
string += ",";
}
string += item.jsonify();
index += 1;
};
JsonableSimple::jsonify(name, string + "]")
}
}

#[cfg(test)]
mod tests {
// Local imports

use super::{Jsonable, JsonableSimple, JsonableString, JsonableArray, JsonableTrait};

#[derive(Drop)]
struct BooleanObject {
value: bool,
}

#[derive(Drop)]
struct IntegerObject {
value: u8,
}

#[derive(Drop)]
struct FeltObject {
value: felt252,
}

#[derive(Drop)]
struct ByteArrayObject {
value: ByteArray,
}

#[derive(Drop)]
struct Complex {
boolean: bool,
integer: u8,
felt: felt252,
byte_array: ByteArray,
array: Array<u8>,
object_array: Array<IntegerObject>,
object: IntegerObject,
}

pub impl IntegerObjectJsonable of JsonableTrait<IntegerObject> {
fn jsonify(self: IntegerObject) -> ByteArray {
let mut string = "{";
string += JsonableSimple::jsonify("value", format!("{}", self.value));
string + "}"
}
}

pub impl BooleanObjectJsonable of JsonableTrait<BooleanObject> {
fn jsonify(self: BooleanObject) -> ByteArray {
let mut string = "{";
string += JsonableSimple::jsonify("value", format!("{}", self.value));
string + "}"
}
}

pub impl FeltObjectJsonable of JsonableTrait<FeltObject> {
fn jsonify(self: FeltObject) -> ByteArray {
let mut string = "{";
string += JsonableSimple::jsonify("value", format!("{}", self.value));
string + "}"
}
}

pub impl ByteArrayObjectJsonable of JsonableTrait<ByteArrayObject> {
fn jsonify(self: ByteArrayObject) -> ByteArray {
let mut string = "{";
string += JsonableString::jsonify("value", format!("{}", self.value));
string + "}"
}
}

pub impl ComplexJsonable of JsonableTrait<Complex> {
fn jsonify(self: Complex) -> ByteArray {
let mut string = "{";
string += JsonableSimple::jsonify("boolean", format!("{}", self.boolean));
string += "," + JsonableSimple::jsonify("integer", format!("{}", self.integer));
string += "," + JsonableSimple::jsonify("felt", format!("{}", self.felt));
string += "," + JsonableString::jsonify("byte_array", format!("{}", self.byte_array));
string += "," + JsonableArray::jsonify("array", self.array);
string += "," + JsonableArray::jsonify("object_array", self.object_array);
string += "," + JsonableSimple::jsonify("object", self.object.jsonify());
string + "}"
}
}

#[test]
fn test_jsonify_integer_object() {
let integer_object = IntegerObject { value: 1 };
let json = integer_object.jsonify();
assert_eq!(json, "{\"value\":1}");
}

#[test]
fn test_jsonify_boolean_object() {
let boolean_object = BooleanObject { value: true };
let json = boolean_object.jsonify();
assert_eq!(json, "{\"value\":true}");
}

#[test]
fn test_jsonify_felt_object() {
let felt_object = FeltObject { value: '1' };
let json = felt_object.jsonify();
assert_eq!(json, "{\"value\":49}");
}

#[test]
fn test_jsonify_byte_array_object() {
let byte_array_object = ByteArrayObject { value: "test" };
let json = byte_array_object.jsonify();
assert_eq!(json, "{\"value\":\"test\"}");
}

#[test]
fn test_jsonify_complex() {
let complex = Complex {
boolean: true,
integer: 1,
felt: '1',
byte_array: "test",
array: array![1, 2, 3],
object_array: array![IntegerObject { value: 1 }, IntegerObject { value: 2 }],
object: IntegerObject { value: 1 },
};
let json = complex.jsonify();
assert_eq!(
json,
"{\"boolean\":true,\"integer\":1,\"felt\":49,\"byte_array\":\"test\",\"array\":[1,2,3],\"object_array\":[{\"value\":1},{\"value\":2}],\"object\":{\"value\":1}}"
);
}
}

16 changes: 16 additions & 0 deletions packages/slot/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
mod constants;
mod store;

mod helpers {
mod json;
}

mod types {
mod tier;
mod status;
}

mod models {
mod index;
mod deployment;
}
157 changes: 157 additions & 0 deletions packages/slot/src/models/deployment.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Intenral imports

use arcade_slot::models::index::Deployment;
use arcade_slot::types::status::Status;
use arcade_slot::types::tier::Tier;

// Errors

pub mod errors {
pub const DEPLOYMENT_ALREADY_EXISTS: felt252 = 'Deployment: already exists';
pub const DEPLOYMENT_NOT_EXIST: felt252 = 'Deployment: does not exist';
pub const DEPLOYMENT_INVALID_IDENTIFIER: felt252 = 'Deployment: invalid identifier';
pub const DEPLOYMENT_INVALID_PROJECT: felt252 = 'Deployment: invalid project';
pub const DEPLOYMENT_INVALID_STATUS: felt252 = 'Deployment: invalid status';
pub const DEPLOYMENT_INVALID_SERVICE_ID: felt252 = 'Deployment: invalid service id';
pub const DEPLOYMENT_INVALID_TIER: felt252 = 'Deployment: invalid tier';
pub const DEPLOYMENT_INVALID_REGIONS: felt252 = 'Deployment: invalid regions';
}

#[generate_trait]
impl DeploymentImpl of DeploymentTrait {
#[inline]
fn new(
id: felt252,
project: felt252,
status: Status,
branch: Option<felt252>,
service_id: felt252,
tier: Tier,
regions: felt252,
auto_upgrade: bool,
config: ByteArray,
) -> Deployment {
// [Check] Inputs
DeploymentAssert::assert_valid_identifier(id);
DeploymentAssert::assert_valid_project(project);
DeploymentAssert::assert_valid_status(status);
DeploymentAssert::assert_valid_service_id(service_id);
DeploymentAssert::assert_valid_tier(tier);
DeploymentAssert::assert_valid_regions(regions);
// [Return] Deployment
let time = starknet::get_block_timestamp();
Deployment {
id: id,
project: project,
status: status.into(),
branch: branch,
service_id: service_id,
tier: tier.into(),
regions: regions,
auto_upgrade: auto_upgrade,
config: config,
created_at: time,
updated_at: time,
spin_down_at: Option::None,
spin_up_at: Option::None,
}
}
}

#[generate_trait]
impl DeploymentAssert of AssertTrait {
#[inline]
fn assert_does_not_exist(self: Deployment) {
assert(self.project == 0, errors::DEPLOYMENT_ALREADY_EXISTS);
}

#[inline]
fn assert_does_exist(self: Deployment) {
assert(self.project != 0, errors::DEPLOYMENT_NOT_EXIST);
}

#[inline]
fn assert_valid_identifier(identifier: felt252) {
assert(identifier != 0, errors::DEPLOYMENT_INVALID_IDENTIFIER);
}

#[inline]
fn assert_valid_project(project: felt252) {
assert(project != 0, errors::DEPLOYMENT_INVALID_PROJECT);
}

#[inline]
fn assert_valid_status(status: Status) {
assert(status != Status::None, errors::DEPLOYMENT_INVALID_STATUS);
}

#[inline]
fn assert_valid_service_id(service_id: felt252) {
assert(service_id != 0, errors::DEPLOYMENT_INVALID_SERVICE_ID);
}

#[inline]
fn assert_valid_tier(tier: Tier) {
assert(tier != Tier::None, errors::DEPLOYMENT_INVALID_TIER);
}

#[inline]
fn assert_valid_regions(regions: felt252) {
assert(regions != 0, errors::DEPLOYMENT_INVALID_REGIONS);
}
}

#[cfg(test)]
mod tests {
// Local imports

use super::{Deployment, DeploymentTrait, DeploymentAssert, Status, Tier};

// Constants

const IDENTIFIER: felt252 = 'ID';
const PROJECT: felt252 = 'PROJECT';
const STATUS: Status = Status::Active;
const BRANCH: Option<felt252> = Option::None;
const SERVICE_ID: felt252 = 'SERVICE_ID';
const TIER: Tier = Tier::Basic;
const REGIONS: felt252 = 'REGIONS';
const AUTO_UPGRADE: bool = true;

#[test]
fn test_deployment_new() {
let deployment = DeploymentTrait::new(
IDENTIFIER, PROJECT, STATUS, BRANCH, SERVICE_ID, TIER, REGIONS, AUTO_UPGRADE, ""
);
assert_eq!(deployment.id, IDENTIFIER);
assert_eq!(deployment.project, PROJECT);
assert_eq!(deployment.status, STATUS.into());
assert_eq!(deployment.branch, BRANCH);
assert_eq!(deployment.service_id, SERVICE_ID);
assert_eq!(deployment.tier, TIER.into());
assert_eq!(deployment.regions, REGIONS);
assert_eq!(deployment.auto_upgrade, AUTO_UPGRADE);
assert_eq!(deployment.config, "");
assert_eq!(deployment.created_at, starknet::get_block_timestamp());
assert_eq!(deployment.updated_at, starknet::get_block_timestamp());
assert_eq!(deployment.spin_down_at, Option::None);
assert_eq!(deployment.spin_up_at, Option::None);
}

#[test]
fn test_deployment_assert_does_exist() {
let deployment = DeploymentTrait::new(
IDENTIFIER, PROJECT, STATUS, BRANCH, SERVICE_ID, TIER, REGIONS, AUTO_UPGRADE, ""
);
deployment.assert_does_exist();
}

#[test]
#[should_panic(expected: 'Deployment: already exists')]
fn test_deployment_revert_already_exists() {
let deployment = DeploymentTrait::new(
IDENTIFIER, PROJECT, STATUS, BRANCH, SERVICE_ID, TIER, REGIONS, AUTO_UPGRADE, ""
);
deployment.assert_does_not_exist();
}
}
Loading

0 comments on commit 7eb097b

Please sign in to comment.