Skip to content

Commit

Permalink
Basic milliseconds type
Browse files Browse the repository at this point in the history
  • Loading branch information
crnbarr93 committed Mar 19, 2024
1 parent 7aa94dc commit d0a81b1
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 72 deletions.
108 changes: 108 additions & 0 deletions packages/std/src/common/milliseconds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Env, Timestamp};
use cw20::Expiration;

#[cw_serde]
/// Represents time in milliseconds.
pub struct Milliseconds(u64);

impl Milliseconds {
pub fn is_block_expired(&self, env: &Env) -> bool {
let time = env.block.time.seconds() * 1000;
self.0 <= time
}

#[inline]
pub fn from_seconds(seconds: u64) -> Milliseconds {
if seconds > u64::MAX / 1000 {
panic!("Overflow: Cannot convert seconds to milliseconds")
}

Milliseconds(seconds * 1000)
}

#[inline]
pub fn from_nanos(nanos: u64) -> Milliseconds {
Milliseconds(nanos / 1000000)
}

#[inline]
pub fn seconds(&self) -> u64 {
self.0 / 1000
}

#[inline]
pub fn nanos(&self) -> u64 {
if self.0 > u64::MAX / 1000000 {
panic!("Overflow: Cannot convert milliseconds time to nanoseconds")
}
self.0 * 1000000
}
}

impl From<Milliseconds> for String {
fn from(time: Milliseconds) -> String {
time.0.to_string()
}
}

impl From<Milliseconds> for Timestamp {
fn from(time: Milliseconds) -> Timestamp {
Timestamp::from_nanos(time.nanos())
}
}

impl From<Milliseconds> for Expiration {
fn from(time: Milliseconds) -> Expiration {
Expiration::AtTime(time.into())
}
}

#[cfg(test)]
mod test {
use cosmwasm_std::testing::mock_env;

use super::*;

struct IsExpiredTestCase {
name: &'static str,
input: u64,
curr_time: u64,
is_expired: bool,
}

#[test]
fn test_is_expired() {
let test_cases: Vec<IsExpiredTestCase> = vec![
IsExpiredTestCase {
name: "valid expiration time (expired)",
input: 0,
curr_time: 1,
is_expired: true,
},
IsExpiredTestCase {
name: "valid expiration time (not expired)",
input: 1,
curr_time: 0,
is_expired: false,
},
IsExpiredTestCase {
name: "same time (expired)",
input: 0,
curr_time: 0,
is_expired: true,
},
];

for test in test_cases {
let input = Milliseconds(test.input);
let curr_time = Milliseconds(test.curr_time);
let mut env = mock_env();
env.block.time = curr_time.into();

let output = input.is_block_expired(&env);

assert_eq!(test.is_expired, output, "Test failed: {}", test.name)
}
}
}
64 changes: 6 additions & 58 deletions packages/std/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
pub mod context;
pub mod expiration;
pub mod queries;
pub mod milliseconds;
pub mod rates;
pub mod reply;
pub mod response;
pub mod withdraw;

pub use milliseconds::*;

use crate::error::ContractError;
use cosmwasm_std::{
ensure, from_binary, has_coins, to_binary, BankMsg, Binary, Coin, CosmosMsg, QuerierWrapper,
SubMsg, Uint128,
ensure, has_coins, to_binary, BankMsg, Binary, Coin, CosmosMsg, SubMsg, Uint128,
};
use cw20::Cw20Coin;

use serde::{de::DeserializeOwned, Serialize};
use serde::Serialize;
use std::collections::BTreeMap;

use cosmwasm_schema::cw_serde;
Expand All @@ -23,24 +24,6 @@ pub enum OrderBy {
Desc,
}

pub fn parse_struct<T>(val: &Binary) -> Result<T, ContractError>
where
T: DeserializeOwned,
{
let data_res = from_binary(val);
match data_res {
Ok(data) => Ok(data),
Err(err) => Err(ContractError::ParsingError {
err: err.to_string(),
}),
}
}

pub fn parse_message<T: DeserializeOwned>(data: &Option<Binary>) -> Result<T, ContractError> {
let data = unwrap_or_err(data, ContractError::MissingRequiredMessageData {})?;
parse_struct::<T>(data)
}

pub fn encode_binary<T>(val: &T) -> Result<Binary, ContractError>
where
T: Serialize,
Expand All @@ -51,24 +34,6 @@ where
}
}

pub fn unwrap_or_err<T>(val_opt: &Option<T>, err: ContractError) -> Result<&T, ContractError> {
match val_opt {
Some(val) => Ok(val),
None => Err(err),
}
}

pub fn query_primitive<T>(
_querier: QuerierWrapper,
_contract_address: String,
_key: Option<String>,
) -> Result<T, ContractError>
where
T: DeserializeOwned,
{
todo!()
}

#[cw_serde]
pub enum Funds {
Native(Coin),
Expand Down Expand Up @@ -214,7 +179,7 @@ pub fn deduct_funds(coins: &mut [Coin], funds: &Coin) -> Result<(), ContractErro

#[cfg(test)]
mod test {
use cosmwasm_std::{coin, to_binary, Uint128, WasmMsg};
use cosmwasm_std::{coin, Uint128, WasmMsg};
use cw20::Expiration;

use super::*;
Expand All @@ -225,23 +190,6 @@ mod test {
expiration: Expiration,
}

#[test]
fn test_parse_struct() {
let valid_json = to_binary(&TestStruct {
name: "John Doe".to_string(),
expiration: Expiration::AtHeight(123),
})
.unwrap();

let test_struct: TestStruct = parse_struct(&valid_json).unwrap();
assert_eq!(test_struct.name, "John Doe");
assert_eq!(test_struct.expiration, Expiration::AtHeight(123));

let invalid_json = to_binary("notavalidteststruct").unwrap();

assert!(parse_struct::<TestStruct>(&invalid_json).is_err())
}

#[test]
fn test_merge_coins() {
let coins = vec![coin(100, "uusd"), coin(100, "uluna")];
Expand Down
14 changes: 0 additions & 14 deletions packages/std/src/common/queries.rs

This file was deleted.

0 comments on commit d0a81b1

Please sign in to comment.