clap_serde_derive/lib.rs
1// Copyright (C) 2022 Davide Peressoni
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU Affero General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU Affero General Public License for more details.
12//
13// You should have received a copy of the GNU Affero General Public License
14// along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16#![doc(
17 html_favicon_url = "https://gitlab.com/DPDmancul/clap-serde-derive/-/raw/main/asstets/logo.svg"
18)]
19#![doc(html_logo_url = "https://gitlab.com/DPDmancul/clap-serde-derive/-/raw/main/assets/logo.svg")]
20#![doc = include_str!("../README.md")]
21#![no_std]
22
23use core::borrow::BorrowMut;
24
25// Re-exports
26pub use clap;
27pub use clap_serde_proc::ClapSerde;
28pub use serde;
29
30/// Trait representing a struct which can be parsed from clap and serde.
31/// This trait is automatically implemented by [`ClapSerde`][clap_serde_proc::ClapSerde]
32/// derive macro.
33pub trait ClapSerde: Default + From<Self::Opt> + for<'a> From<&'a mut Self::Opt> {
34 /// The same struct of the parent but with optional fields.
35 type Opt: Default + clap::Parser + serde::de::DeserializeOwned + clap::Args;
36
37 /// Merge in place from Opt struct.
38 ///
39 /// Fields which are not None in `other` will be cleared and used to update `self`.
40 /// Fields which are None in `other` will not be modified in `self`.
41 fn update(&mut self, other: impl BorrowMut<Self::Opt>);
42
43 /// Merge from Opts struct.
44 fn merge(mut self, other: impl BorrowMut<Self::Opt>) -> Self {
45 self.update(other);
46 self
47 }
48
49 /// Merge from clap to the object.
50 fn merge_clap(self) -> Self {
51 self.merge(<Self::Opt as clap::Parser>::parse())
52 }
53 /// Create new object parsing from clap.
54 fn from_clap() -> Self {
55 Self::default().merge_clap()
56 }
57}