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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use std::{error::Error, ffi::CStr};

use serde::{Deserialize, Serialize};

use crate::{ai_interface::AIInterface, get_callback};

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Resource {
    pub ai_id: i32,
    pub resource_id: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceInterface {
    pub ai_id: i32,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceAll {
    name: String,
    optimum: f32,
    current: f32,
    income: f32,
    usage: f32,
    storage: f32,
    pull: f32,
    share: f32,
    sent: f32,
    received: f32,
    excess: f32,
}

impl AIInterface {
    pub fn resource_interface(&self) -> ResourceInterface {
        ResourceInterface { ai_id: self.ai_id }
    }
}

impl ResourceInterface {
    pub fn get_resources(&self) -> Result<Vec<Resource>, Box<dyn Error>> {
        let get_resources = get_callback!(self.ai_id, getResources)?;

        Ok((0..unsafe { get_resources(self.ai_id) })
            .map(|i| Resource {
                ai_id: self.ai_id,
                resource_id: i,
            })
            .collect())
    }
}

impl Resource {
    pub fn name(&self) -> Result<String, Box<dyn Error>> {
        let get_resource_name = get_callback!(self.ai_id, Resource_getName)?;

        Ok(String::from(
            unsafe { CStr::from_ptr(get_resource_name(self.ai_id, self.resource_id)) }.to_str()?,
        ))
    }

    pub fn optimum(&self) -> Result<f32, Box<dyn Error>> {
        let get_resource_optimum = get_callback!(self.ai_id, Resource_getOptimum)?;
        Ok(unsafe { get_resource_optimum(self.ai_id, self.resource_id) })
    }

    pub fn current(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_current = get_callback!(self.ai_id, Economy_getCurrent)?;
        Ok(unsafe { get_economy_current(self.ai_id, self.resource_id) })
    }

    pub fn income(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_income = get_callback!(self.ai_id, Economy_getIncome)?;
        Ok(unsafe { get_economy_income(self.ai_id, self.resource_id) })
    }

    pub fn usage(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_usage = get_callback!(self.ai_id, Economy_getUsage)?;
        Ok(unsafe { get_economy_usage(self.ai_id, self.resource_id) })
    }

    pub fn storage(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_storage = get_callback!(self.ai_id, Economy_getStorage)?;
        Ok(unsafe { get_economy_storage(self.ai_id, self.resource_id) })
    }

    pub fn pull(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_pull = get_callback!(self.ai_id, Economy_getPull)?;
        Ok(unsafe { get_economy_pull(self.ai_id, self.resource_id) })
    }

    pub fn share(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_share = get_callback!(self.ai_id, Economy_getShare)?;
        Ok(unsafe { get_economy_share(self.ai_id, self.resource_id) })
    }

    pub fn sent(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_sent = get_callback!(self.ai_id, Economy_getSent)?;
        Ok(unsafe { get_economy_sent(self.ai_id, self.resource_id) })
    }

    pub fn received(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_received = get_callback!(self.ai_id, Economy_getReceived)?;
        Ok(unsafe { get_economy_received(self.ai_id, self.resource_id) })
    }

    pub fn excess(&self) -> Result<f32, Box<dyn Error>> {
        let get_economy_excess = get_callback!(self.ai_id, Economy_getExcess)?;
        Ok(unsafe { get_economy_excess(self.ai_id, self.resource_id) })
    }

    pub fn all(&self) -> Result<ResourceAll, Box<dyn Error>> {
        Ok(ResourceAll {
            name: self.name()?,
            optimum: self.optimum()?,
            current: self.current()?,
            income: self.income()?,
            usage: self.usage()?,
            storage: self.storage()?,
            pull: self.pull()?,
            share: self.share()?,
            sent: self.sent()?,
            received: self.received()?,
            excess: self.excess()?,
        })
    }
}