payjp_core/
plan.rs

1/// planオブジェクト
2///
3/// For more details see <<https://pay.jp/docs/api>>.
4#[derive(Clone,Debug,)]#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
5#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
6pub struct Plan {
7    /// プランの料金
8pub amount: i64,
9    /// 課金日。1から31の整数で指定可能。nullの場合は課金日を指定しない。
10pub billing_day: Option<i64>,
11    /// プラン作成時のタイムスタンプ
12pub created: i64,
13    /// 3文字のISOコード(現状 "jpy" のみサポート)
14pub currency: String,
15    /// `pln_`で始まる一意なオブジェクトを示す文字列
16pub id: payjp_core::PlanId,
17    /// 課金の間隔。`day`, `week`, `month`, `year` のいずれか。
18pub interval: PlanInterval,
19    /// 本番環境かどうか
20pub livemode: bool,
21    /// キーバリューの任意データ
22#[cfg_attr(any(feature = "deserialize", feature = "serialize"), serde(with = "payjp_types::with_serde_json_opt"))]
23pub metadata: Option<miniserde::json::Value>,
24    /// プラン名
25pub name: String,
26    /// "plan"の固定文字列
27pub object: String,
28    /// トライアル期間の日数
29pub trial_days: u32,
30
31}
32#[doc(hidden)]
33pub struct PlanBuilder {
34    amount: Option<i64>,
35billing_day: Option<Option<i64>>,
36created: Option<i64>,
37currency: Option<String>,
38id: Option<payjp_core::PlanId>,
39interval: Option<PlanInterval>,
40livemode: Option<bool>,
41metadata: Option<Option<miniserde::json::Value>>,
42name: Option<String>,
43object: Option<String>,
44trial_days: Option<u32>,
45
46}
47
48#[allow(unused_variables, irrefutable_let_patterns, clippy::let_unit_value, clippy::match_single_binding, clippy::single_match)]
49const _: () = {
50    use miniserde::de::{Map, Visitor};
51    use miniserde::json::Value;
52    use miniserde::{make_place, Deserialize, Result};
53    use payjp_types::{MapBuilder, ObjectDeser};
54    use payjp_types::miniserde_helpers::FromValueOpt;
55
56    make_place!(Place);
57
58    impl Deserialize for Plan {
59    fn begin(out: &mut Option<Self>) -> &mut dyn Visitor {
60       Place::new(out)
61    }
62}
63
64struct Builder<'a> {
65    out: &'a mut Option<Plan>,
66    builder: PlanBuilder,
67}
68
69impl Visitor for Place<Plan> {
70    fn map(&mut self) -> Result<Box<dyn Map + '_>> {
71        Ok(Box::new(Builder {
72            out: &mut self.out,
73            builder: PlanBuilder::deser_default(),
74        }))
75    }
76}
77
78impl MapBuilder for PlanBuilder {
79    type Out = Plan;
80    fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
81        Ok(match k {
82            "amount" => Deserialize::begin(&mut self.amount),
83"billing_day" => Deserialize::begin(&mut self.billing_day),
84"created" => Deserialize::begin(&mut self.created),
85"currency" => Deserialize::begin(&mut self.currency),
86"id" => Deserialize::begin(&mut self.id),
87"interval" => Deserialize::begin(&mut self.interval),
88"livemode" => Deserialize::begin(&mut self.livemode),
89"metadata" => Deserialize::begin(&mut self.metadata),
90"name" => Deserialize::begin(&mut self.name),
91"object" => Deserialize::begin(&mut self.object),
92"trial_days" => Deserialize::begin(&mut self.trial_days),
93
94            _ => <dyn Visitor>::ignore(),
95        })
96    }
97
98    fn deser_default() -> Self {
99        Self {
100            amount: Deserialize::default(),
101billing_day: Deserialize::default(),
102created: Deserialize::default(),
103currency: Deserialize::default(),
104id: Deserialize::default(),
105interval: Deserialize::default(),
106livemode: Deserialize::default(),
107metadata: Deserialize::default(),
108name: Deserialize::default(),
109object: Deserialize::default(),
110trial_days: Deserialize::default(),
111
112        }
113    }
114
115    fn take_out(&mut self) -> Option<Self::Out> {
116        let (Some(amount),
117Some(billing_day),
118Some(created),
119Some(currency),
120Some(id),
121Some(interval),
122Some(livemode),
123Some(metadata),
124Some(name),
125Some(object),
126Some(trial_days),
127) = (self.amount,
128self.billing_day,
129self.created,
130self.currency.take(),
131self.id.take(),
132self.interval,
133self.livemode,
134self.metadata.take(),
135self.name.take(),
136self.object.take(),
137self.trial_days,
138) else {
139            return None;
140        };
141        Some(Self::Out { amount,billing_day,created,currency,id,interval,livemode,metadata,name,object,trial_days })
142    }
143}
144
145impl<'a> Map for Builder<'a> {
146    fn key(&mut self, k: &str) -> Result<&mut dyn Visitor> {
147        self.builder.key(k)
148    }
149
150    fn finish(&mut self) -> Result<()> {
151        *self.out = self.builder.take_out();
152        Ok(())
153    }
154}
155
156impl ObjectDeser for Plan {
157    type Builder = PlanBuilder;
158}
159
160impl FromValueOpt for Plan {
161    fn from_value(v: Value) -> Option<Self> {
162        let Value::Object(obj) = v else {
163            return None;
164        };
165        let mut b = PlanBuilder::deser_default();
166        for (k, v) in obj {
167            match k.as_str() {
168                "amount" => b.amount = FromValueOpt::from_value(v),
169"billing_day" => b.billing_day = FromValueOpt::from_value(v),
170"created" => b.created = FromValueOpt::from_value(v),
171"currency" => b.currency = FromValueOpt::from_value(v),
172"id" => b.id = FromValueOpt::from_value(v),
173"interval" => b.interval = FromValueOpt::from_value(v),
174"livemode" => b.livemode = FromValueOpt::from_value(v),
175"metadata" => b.metadata = FromValueOpt::from_value(v),
176"name" => b.name = FromValueOpt::from_value(v),
177"object" => b.object = FromValueOpt::from_value(v),
178"trial_days" => b.trial_days = FromValueOpt::from_value(v),
179
180                _ => {}
181            }
182        }
183        b.take_out()
184    }
185}
186
187};
188/// 課金の間隔。`day`, `week`, `month`, `year` のいずれか。
189#[derive(Copy,Clone,Eq, PartialEq,)]pub enum PlanInterval {
190Day,
191Week,
192Month,
193Year,
194
195}
196impl PlanInterval {
197    pub fn as_str(self) -> &'static str {
198        use PlanInterval::*;
199        match self {
200Day => "day",
201Week => "week",
202Month => "month",
203Year => "year",
204
205        }
206    }
207}
208
209impl std::str::FromStr for PlanInterval {
210    type Err = payjp_types::ParseError;
211    fn from_str(s: &str) -> Result<Self, Self::Err> {
212        use PlanInterval::*;
213        match s {
214    "day" => Ok(Day),
215"week" => Ok(Week),
216"month" => Ok(Month),
217"year" => Ok(Year),
218_ => Err(payjp_types::ParseError)
219
220        }
221    }
222}
223impl std::fmt::Display for PlanInterval {
224    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
225        f.write_str(self.as_str())
226    }
227}
228
229impl std::fmt::Debug for PlanInterval {
230    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
231        f.write_str(self.as_str())
232    }
233}
234#[cfg(feature = "serialize")]
235impl serde::Serialize for PlanInterval {
236    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
237        serializer.serialize_str(self.as_str())
238    }
239}
240impl miniserde::Deserialize for PlanInterval {
241    fn begin(out: &mut Option<Self>) -> &mut dyn miniserde::de::Visitor {
242        crate::Place::new(out)
243    }
244}
245
246impl miniserde::de::Visitor for crate::Place<PlanInterval> {
247    fn string(&mut self, s: &str) -> miniserde::Result<()> {
248        use std::str::FromStr;
249        self.out = Some(PlanInterval::from_str(s).map_err(|_| miniserde::Error)?);
250        Ok(())
251    }
252}
253
254payjp_types::impl_from_val_with_from_str!(PlanInterval);
255#[cfg(feature = "deserialize")]
256impl<'de> serde::Deserialize<'de> for PlanInterval {
257    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
258        use std::str::FromStr;
259        let s: std::borrow::Cow<'de, str> = serde::Deserialize::deserialize(deserializer)?;
260        Self::from_str(&s).map_err(|_| serde::de::Error::custom("Unknown value for PlanInterval"))
261    }
262}
263impl payjp_types::Object for Plan {
264    type Id = payjp_core::PlanId;
265    fn id(&self) -> &Self::Id {
266        &self.id
267    }
268
269    fn into_id(self) -> Self::Id {
270        self.id
271    }
272}
273payjp_types::def_id!(PlanId);