-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
98f31a0
commit 75e4e15
Showing
3 changed files
with
411 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
use chrono::format; | ||
|
||
use crate::models::*; | ||
|
||
use super::super::AssetType; | ||
use super::super::Order; | ||
|
||
/// SingleClaimableBalanceRequest is the struct that implements the type for the /claimable_balances endpoint to get a single claimable balance | ||
/// [More Details](https://laboratory.stellar.org/#explorer?resource=claimable_balances&endpoint=single&network=test "Single Claimable Balance") | ||
#[derive(Debug)] | ||
pub struct SingleClaimableBalanceRequest { | ||
/// Claimable Balance ID | ||
/// [Stellar Documentation](https://developers.stellar.org/api/resources/claimablebalances/single/ "Claimable Balance ID") | ||
claimable_balance_id: Option<String>, | ||
} | ||
|
||
impl Request for SingleClaimableBalanceRequest { | ||
/// Creates a new request object | ||
/// # Returns | ||
/// A new request object | ||
/// [SingleClaimableBalanceRequest](struct.SingleClaimableBalanceRequest.html) | ||
fn new() -> Self { | ||
SingleClaimableBalanceRequest { | ||
claimable_balance_id: None, | ||
} | ||
} | ||
|
||
/// Gets the relative URL for the request | ||
/// # Returns | ||
/// The relative URL for the request | ||
fn get_path(&self) -> &str { | ||
"/claimable_balances/" | ||
} | ||
|
||
/// Gets the query parameters for the request | ||
/// # Returns | ||
/// The query parameters for the request | ||
fn get_query_parameters(&self) -> String { | ||
let mut query = String::new(); | ||
if let Some(claimable_balance_id) = &self.claimable_balance_id { | ||
query.push_str(&format!("{}", claimable_balance_id)); | ||
} | ||
query | ||
} | ||
|
||
/// Builds the URL for the request | ||
/// # Arguments | ||
/// * `self` - The request object | ||
/// * `base_url` - The base URL for the Horizon server | ||
/// # Returns | ||
/// The URL for the request | ||
fn build_url(&self, base_url: &str) -> String { | ||
println!("\n\nBUILD URL: {:?}", format!( | ||
"{}{}{}", | ||
base_url, | ||
self.get_path(), | ||
self.get_query_parameters() | ||
)); | ||
|
||
format!( | ||
"{}{}{}", | ||
base_url, | ||
self.get_path(), | ||
self.get_query_parameters() | ||
) | ||
} | ||
|
||
/// Returns the type of request | ||
/// # Returns | ||
/// The type of request | ||
/// [RequestType](../enum.RequestType.html) | ||
/// [More Details](https://laboratory.stellar.org/#explorer?resource=claimable_balances&endpoint=single&network=test "Single Claimable Balance") | ||
fn validate(&self) -> Result<(), String> { | ||
|
||
// TODO: Validate claimable_balance_id | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
/// Returns the claimable balance ID | ||
/// # Arguments | ||
/// * `self` - The request object | ||
/// # Returns | ||
/// The claimable balance ID | ||
impl SingleClaimableBalanceRequest { | ||
pub fn set_claimable_balance_id(&mut self, claimable_balance_id: String) -> &mut Self { | ||
self.claimable_balance_id = Some(claimable_balance_id); | ||
self | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
use chrono::DateTime; | ||
use chrono::Utc; | ||
use derive_getters::Getters; | ||
use serde::Deserialize; | ||
use serde::Serialize; | ||
|
||
use crate::models::Response; | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct SingleClaimableBalanceResponse { | ||
#[serde(rename = "_links")] | ||
pub links: Links, | ||
pub id: String, | ||
pub asset: String, | ||
pub amount: String, | ||
pub sponsor: String, | ||
#[serde(rename = "last_modified_ledger")] | ||
pub last_modified_ledger: i64, | ||
#[serde(rename = "last_modified_time")] | ||
pub last_modified_time: String, | ||
pub claimants: Vec<Claimant>, | ||
pub flags: Flags, | ||
#[serde(rename = "paging_token")] | ||
pub paging_token: String, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Links { | ||
#[serde(rename = "self")] | ||
pub self_field: Self_field, | ||
pub transactions: Transactions, | ||
pub operations: Operations, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Self_field { | ||
pub href: String, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Transactions { | ||
pub href: String, | ||
pub templated: bool, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Operations { | ||
pub href: String, | ||
pub templated: bool, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Claimant { | ||
pub destination: String, | ||
pub predicate: Predicate, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Predicate { | ||
pub unconditional: Option<bool>, | ||
pub or: Option<Vec<Or>>, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Or { | ||
pub and: Option<Vec<And>>, | ||
#[serde(rename = "abs_before")] | ||
pub abs_before: Option<String>, | ||
#[serde(rename = "abs_before_epoch")] | ||
pub abs_before_epoch: Option<String>, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct And { | ||
pub not: Option<Not>, | ||
#[serde(rename = "abs_before")] | ||
pub abs_before: Option<String>, | ||
#[serde(rename = "abs_before_epoch")] | ||
pub abs_before_epoch: Option<String>, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Not { | ||
#[serde(rename = "abs_before")] | ||
pub abs_before: String, | ||
#[serde(rename = "abs_before_epoch")] | ||
pub abs_before_epoch: String, | ||
} | ||
|
||
#[derive(Default, Debug, Clone, Serialize, Deserialize, Getters)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct Flags { | ||
#[serde(rename = "clawback_enabled")] | ||
pub clawback_enabled: bool, | ||
} | ||
|
||
impl Response for SingleClaimableBalanceResponse { | ||
fn from_json(json: String) -> Result<Self, String> { | ||
let response = serde_json::from_str(&json).map_err(|e| e.to_string())?; | ||
|
||
Ok(response) | ||
} | ||
} | ||
|
||
impl Predicate { | ||
// This method checks if a claim is valid at a specific datetime. | ||
pub fn is_valid_claim(&self, datetime: DateTime<Utc>) -> bool { | ||
// If the predicate is marked as unconditional, the claim is always valid. | ||
if let Some(true) = self.unconditional { | ||
true | ||
} | ||
// If there are 'or' conditions, check if any of these conditions validate the claim. | ||
else if let Some(or_conditions) = &self.or { | ||
or_conditions.iter().any(|or| or.is_valid(datetime)) | ||
} | ||
// If there are no conditions, the claim is valid. | ||
else { | ||
true | ||
} | ||
} | ||
} | ||
|
||
|
||
impl Or { | ||
// This method checks if any condition under 'or' validates the claim. | ||
fn is_valid(&self, datetime: DateTime<Utc>) -> bool { | ||
// If there are 'and' conditions, check if any combination of these conditions is valid. | ||
if let Some(and_conditions) = &self.and { | ||
and_conditions.iter().any(|and| and.is_valid(datetime)) | ||
} | ||
// If there is an 'abs_before' condition, check if the datetime is before this date. | ||
else if let Some(abs_before) = &self.abs_before { | ||
if let Ok(abs_before_date) = DateTime::parse_from_rfc3339(abs_before) { | ||
datetime < abs_before_date | ||
} else { | ||
false | ||
} | ||
} | ||
// If no specific condition is found, the claim is valid. | ||
else { | ||
true | ||
} | ||
} | ||
} | ||
|
||
impl And { | ||
// This method checks if all conditions under 'and' are met. | ||
fn is_valid(&self, datetime: DateTime<Utc>) -> bool { | ||
let mut is_valid = true; | ||
|
||
// If there is an 'abs_before' condition, check if the datetime is before this date. | ||
if let Some(abs_before) = &self.abs_before { | ||
if let Ok(abs_before_date) = DateTime::parse_from_rfc3339(abs_before) { | ||
is_valid &= datetime < abs_before_date; | ||
} | ||
} | ||
|
||
// If there is a 'not' condition, it should also validate the datetime. | ||
if let Some(not_condition) = &self.not { | ||
is_valid &= not_condition.is_valid(datetime); | ||
} | ||
|
||
is_valid | ||
} | ||
} | ||
|
||
impl Not { | ||
// This method checks if the datetime does not fall before the specified date, negating the condition. | ||
fn is_valid(&self, datetime: DateTime<Utc>) -> bool { | ||
if let Ok(not_before_date) = DateTime::parse_from_rfc3339(&self.abs_before) { | ||
datetime >= not_before_date | ||
} else { | ||
false | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.