devhub-shared 0.1.0

A brief description of what the crate does
Documentation
use near_sdk::near;

pub type TimelineStatus = TimelineStatusV2;
type ReviewStatus = ReviewStatusV2;

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
#[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")]
pub enum TimelineStatusV1 {
    Draft,
    Review(ReviewStatusV1),
    Approved(ReviewStatusV1),
    Rejected(ReviewStatusV1),
    ApprovedConditionally(ReviewStatusV1),
    PaymentProcessing(PaymentProcessingStatusV1),
    Funded(FundedStatusV1),
    Cancelled(ReviewStatusV1),
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
#[serde(tag = "timeline_version")]
pub enum VersionedTimelineStatus {
    V1(TimelineStatusV2),
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
#[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")]
pub enum TimelineStatusV2 {
    Draft,
    Review(ReviewStatusV2),
    Approved(ReviewStatusV2),
    Rejected(ReviewStatusV2),
    ApprovedConditionally(ReviewStatusV2),
    PaymentProcessing(PaymentProcessingStatusV2),
    Funded(FundedStatusV2),
    Cancelled(ReviewStatusV2),
}

fn convert_review_status_to_v1(
    review_status: ReviewStatusV1,
    kyc_verified: bool,
) -> ReviewStatusV2 {
    ReviewStatusV2 {
        sponsor_requested_review: review_status.sponsor_requested_review,
        reviewer_completed_attestation: review_status.reviewer_completed_attestation,
        kyc_verified: kyc_verified,
    }
}

impl From<PaymentProcessingStatusV1> for PaymentProcessingStatusV2 {
    fn from(value: PaymentProcessingStatusV1) -> Self {
        PaymentProcessingStatusV2 {
            review_status: convert_review_status_to_v1(value.review_status, value.kyc_verified),
            kyc_verified_deprecated: false,
            test_transaction_sent: value.test_transaction_sent,
            request_for_trustees_created: value.request_for_trustees_created,
        }
    }
}

impl From<FundedStatusV1> for FundedStatusV2 {
    fn from(value: FundedStatusV1) -> Self {
        FundedStatusV2 {
            payment_processing_status: value.payment_processing_status.into(),
            trustees_released_payment: value.trustees_released_payment,
            payouts: value.payouts,
        }
    }
}

impl From<TimelineStatusV1> for TimelineStatusV2 {
    fn from(value: TimelineStatusV1) -> Self {
        match value {
            TimelineStatusV1::Draft => TimelineStatusV2::Draft,
            TimelineStatusV1::Review(review_status) => {
                TimelineStatusV2::Review(convert_review_status_to_v1(review_status, false))
            }
            TimelineStatusV1::Approved(review_status) => {
                TimelineStatusV2::Approved(convert_review_status_to_v1(review_status, false))
            }
            TimelineStatusV1::Rejected(review_status) => {
                TimelineStatusV2::Rejected(convert_review_status_to_v1(review_status, false))
            }
            TimelineStatusV1::ApprovedConditionally(review_status) => {
                TimelineStatusV2::ApprovedConditionally(convert_review_status_to_v1(
                    review_status,
                    false,
                ))
            }
            TimelineStatusV1::PaymentProcessing(payment_processing_status) => {
                TimelineStatusV2::PaymentProcessing(payment_processing_status.into())
            }
            TimelineStatusV1::Funded(funded_status) => {
                TimelineStatusV2::Funded(funded_status.into())
            }
            TimelineStatusV1::Cancelled(review_status) => {
                TimelineStatusV2::Cancelled(convert_review_status_to_v1(review_status, false))
            }
        }
    }
}

impl VersionedTimelineStatus {
    pub fn latest_version(self) -> TimelineStatus {
        self.into()
    }
}

impl From<VersionedTimelineStatus> for TimelineStatusV2 {
    fn from(value: VersionedTimelineStatus) -> Self {
        match value {
            VersionedTimelineStatus::V1(v1) => v1,
        }
    }
}

impl From<TimelineStatusV2> for VersionedTimelineStatus {
    fn from(value: TimelineStatusV2) -> Self {
        VersionedTimelineStatus::V1(value)
    }
}

impl From<TimelineStatusV1> for VersionedTimelineStatus {
    fn from(value: TimelineStatusV1) -> Self {
        VersionedTimelineStatus::V1(value.into())
    }
}

impl TimelineStatus {
    pub fn is_draft(&self) -> bool {
        matches!(self, TimelineStatus::Draft)
    }

    pub fn is_empty_review(&self) -> bool {
        match self {
            TimelineStatus::Review(review_status) => {
                !review_status.sponsor_requested_review
                    && !review_status.reviewer_completed_attestation
            }
            _ => false,
        }
    }

    pub fn is_review(&self) -> bool {
        matches!(self, TimelineStatus::Review(..))
    }

    pub fn is_cancelled(&self) -> bool {
        matches!(self, TimelineStatus::Cancelled(..))
    }

    pub fn can_be_cancelled(&self) -> bool {
        match self {
            TimelineStatus::Draft => true,
            TimelineStatus::Review(..) => true,
            _ => false,
        }
    }

    pub fn was_approved(&self) -> bool {
        match self {
            TimelineStatus::Approved(..) => true,
            TimelineStatus::ApprovedConditionally(..) => true,
            TimelineStatus::PaymentProcessing(..) => true,
            TimelineStatus::Funded(..) => true,
            _ => false,
        }
    }

    pub fn get_review_status(&self) -> &ReviewStatus {
        match self {
            TimelineStatus::Review(review_status)
            | TimelineStatus::Approved(review_status)
            | TimelineStatus::Rejected(review_status)
            | TimelineStatus::ApprovedConditionally(review_status)
            | TimelineStatus::Cancelled(review_status) => review_status.into(),
            TimelineStatus::PaymentProcessing(payment_processing_status) => {
                &payment_processing_status.review_status
            }
            TimelineStatus::Funded(funded_status) => {
                &funded_status.payment_processing_status.review_status
            }
            TimelineStatus::Draft => &ReviewStatus {
                sponsor_requested_review: false,
                reviewer_completed_attestation: false,
                kyc_verified: false,
            },
        }
    }
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
pub struct ReviewStatusV1 {
    sponsor_requested_review: bool,
    reviewer_completed_attestation: bool,
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
pub struct ReviewStatusV2 {
    sponsor_requested_review: bool,
    reviewer_completed_attestation: bool,
    kyc_verified: bool,
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
pub struct PaymentProcessingStatusV1 {
    #[serde(flatten)]
    review_status: ReviewStatusV1,
    kyc_verified: bool,
    test_transaction_sent: bool,
    request_for_trustees_created: bool,
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
pub struct PaymentProcessingStatusV2 {
    #[serde(flatten)]
    review_status: ReviewStatusV2,
    #[serde(default)]
    kyc_verified_deprecated: bool,
    test_transaction_sent: bool,
    request_for_trustees_created: bool,
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
pub struct FundedStatusV1 {
    #[serde(flatten)]
    payment_processing_status: PaymentProcessingStatusV1,
    trustees_released_payment: bool,
    payouts: Vec<String>,
}

#[near(serializers=[borsh, json])]
#[derive(Clone, Debug)]
pub struct FundedStatusV2 {
    #[serde(flatten)]
    payment_processing_status: PaymentProcessingStatusV2,
    trustees_released_payment: bool,
    payouts: Vec<String>,
}