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
use std::collections::HashMap;

use {
    super::{AssociatedProgram, Indexing, ProfileData, Service},
    anchor_lang::prelude::*,
    hpl_utils::Default,
};

/// Project State Account
/// This account represents the cenntralized state and confnigurations of an NFT project on the Honeycomb Protocol.
/// PDA: ['project', key]
/// Category: project_state
#[account]
#[derive(PartialEq, Eq, Debug)]
pub struct Project {
    /// Bump value used for PDA.
    pub bump: u8,

    /// Public key of the authority controlling this project.
    pub authority: Pubkey,

    /// Unique public key identifier for this project account.
    pub key: Pubkey,

    /// Public key of the driver wallet having partial authority of this project.
    pub driver: Pubkey,

    /// Name of the project.
    pub name: String,

    /// Indexing information for the associated mints of the NFT Collection.
    pub mint_indexing: Indexing,

    /// List of honeycomb services associated with this project.
    pub services: Vec<Service>,

    /// List of nft collections (public keys) associated with this project.
    pub collections: Vec<Pubkey>,

    /// List of public keys representing the nft creators involved in this project.
    pub creators: Vec<Pubkey>,

    /// Configuration for profile data stored as key-value pairs in a HashMap.
    pub profile_data_config: HashMap<String, ProfileDataType>,

    /// List of public keys representing the nft creators involved in this project.
    pub merkle_trees: Vec<Pubkey>,
    pub associated_programs: Vec<AssociatedProgram>,
}

/// Default implementation for the `Project` struct.
/// It sets default values for each field when creating a new `Project` instance.
impl Default for Project {
    const LEN: usize = 256 + 8; // base size + 8 align

    /// Sets default values for each field of the `Project` struct.
    fn set_defaults(&mut self) {
        self.bump = 0;
        self.key = Pubkey::default();
        self.driver = Pubkey::default();
        self.name = "".to_string();
        self.mint_indexing = Indexing::default();
        self.services = vec![];
        self.collections = vec![];
        self.creators = vec![];
        self.associated_programs = vec![];
        self.profile_data_config = HashMap::new();
        self.merkle_trees = vec![];
    }
}

impl Project {
    pub fn validate_profile_data(&self, label: &String, profile_data: &ProfileData) -> bool {
        let profile_data_type = self.profile_data_config.get(label).unwrap();
        match profile_data_type {
            ProfileDataType::SingleValue => {
                matches!(profile_data, ProfileData::SingleValue(_))
            }
            ProfileDataType::MultiValue => {
                matches!(profile_data, ProfileData::MultiValue(_))
            }
        }
    }
}

/// Enum representing the different types of profile data for the `ProfileDataType` field
/// in the `Project` struct.
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, Eq, PartialEq)]
pub enum ProfileDataType {
    /// Single value profile data.
    SingleValue,

    /// Multi-value profile data.
    MultiValue,
}

/// Implementation for the `ProfileDataType` enum.
impl ProfileDataType {
    /// Length of the `ProfileDataType` enum in bytes.
    pub const LEN: usize = 1;
}