Skip to main content

nil_core/market/
mod.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4pub mod fee;
5pub mod vault;
6
7use crate::market::fee::MarketFee;
8use crate::market::vault::MarketVault;
9use crate::resources::gold::Gold;
10use crate::resources::{Food, Iron, Stone, Wood};
11use serde::{Deserialize, Serialize};
12use std::marker::PhantomData;
13
14#[derive(Clone, Debug, Deserialize, Serialize)]
15#[derive_const(Default)]
16#[serde(rename_all = "camelCase")]
17#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
18pub struct Market {
19  vault: MarketVault,
20  fee: MarketFee,
21
22  // We don't *strictly* need to include the market price here,
23  // since it can be derived from the resources themselves.
24  // However, including it simplifies things for downstream consumers,
25  // as they don't need to query the resources separately to obtain it.
26  #[cfg_attr(feature = "typescript", ts(as = "MarketPrice"))]
27  #[cfg_attr(
28    not(feature = "typescript"),
29    serde(skip_deserializing, serialize_with = "serialize_market_price")
30  )]
31  price: PhantomData<MarketPrice>,
32}
33
34impl Market {
35  pub const fn new(fee: MarketFee) -> Self {
36    Self {
37      vault: MarketVault::default(),
38      fee: fee.clamped(),
39      price: PhantomData,
40    }
41  }
42
43  #[inline]
44  pub const fn vault(&self) -> &MarketVault {
45    &self.vault
46  }
47
48  pub(crate) const fn vault_mut(&mut self) -> &mut MarketVault {
49    &mut self.vault
50  }
51
52  #[inline]
53  pub const fn fee(&self) -> MarketFee {
54    self.fee
55  }
56
57  #[inline]
58  pub const fn price(&self) -> MarketPrice {
59    MarketPrice::default()
60  }
61
62  /// Sets the market fee, clamping it to the valid range.
63  ///
64  /// As the fee is not expected to be changed throughout the game,
65  /// this should only be used to execute cheats or for testing purposes.
66  pub(crate) const fn set_fee(&mut self, fee: MarketFee) {
67    self.fee = fee.clamped();
68  }
69}
70
71#[derive(Copy, Debug, Deserialize, Serialize)]
72#[derive_const(Clone, PartialEq, Eq)]
73#[serde(rename_all = "camelCase")]
74#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
75pub struct MarketPrice {
76  food: Gold,
77  iron: Gold,
78  stone: Gold,
79  wood: Gold,
80}
81
82impl MarketPrice {
83  pub const fn new() -> Self {
84    Self::default()
85  }
86}
87
88const impl Default for MarketPrice {
89  fn default() -> Self {
90    Self {
91      food: Food::MARKET_PRICE,
92      iron: Iron::MARKET_PRICE,
93      stone: Stone::MARKET_PRICE,
94      wood: Wood::MARKET_PRICE,
95    }
96  }
97}
98
99#[cfg(not(feature = "typescript"))]
100#[allow(clippy::trivially_copy_pass_by_ref)]
101fn serialize_market_price<S>(_: &PhantomData<MarketPrice>, serializer: S) -> Result<S::Ok, S::Error>
102where
103  S: serde::Serializer,
104{
105  MarketPrice::default().serialize(serializer)
106}