oceanpkg/drop/source/
git.rs1use std::fmt;
4use serde::{Serialize, Serializer};
5
6pub const OCEAN_REPO: &str = env!("CARGO_PKG_REPOSITORY");
8
9flexible! {
10 #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
12 pub struct Git {
13 #[serde(alias = "repository")]
15 pub repo: String,
16 #[serde(flatten)]
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub reference: Option<Ref>,
20 }
21}
22
23impl From<String> for Git {
24 #[inline]
25 fn from(repo: String) -> Self {
26 Self { repo, reference: None }
27 }
28}
29
30impl Git {
31 pub fn new<A, B>(repo: A, reference: B) -> Self
33 where
34 A: Into<String>,
35 B: Into<Option<Ref>>,
36 {
37 Self {
38 repo: repo.into(),
39 reference: reference.into(),
40 }
41 }
42
43 #[inline]
45 pub fn write_toml(&self, f: &mut fmt::Formatter) -> fmt::Result {
46 write!(f, r#"git = {{ repo = "{}""#, self.repo)?;
47 if let Some(reference) = &self.reference {
48 write!(f, r#", {} = "{}""#, reference.kind(), reference)?;
49 }
50 write!(f, " }}")
51 }
52
53 #[inline]
55 pub fn display_toml<'a>(&'a self) -> impl fmt::Display + Copy + 'a {
56 #[derive(Clone, Copy)]
57 struct Displayer<'a>(&'a Git);
58
59 impl fmt::Display for Displayer<'_> {
60 #[inline]
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 self.0.write_toml(f)
63 }
64 }
65
66 Displayer(self)
67 }
68}
69
70#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize)]
72#[serde(rename_all = "lowercase")]
73pub enum Ref {
74 Branch(String),
78 Tag(String),
80 Rev(String),
82}
83
84impl Default for Ref {
85 #[inline]
86 fn default() -> Self {
87 Self::master()
88 }
89}
90
91impl fmt::Display for Ref {
92 #[inline]
93 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
94 self.as_str().fmt(f)
95 }
96}
97
98impl AsRef<str> for Ref {
99 #[inline]
100 fn as_ref(&self) -> &str {
101 self.as_str()
102 }
103}
104
105impl Serialize for Ref {
106 fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
107 where S: Serializer
108 {
109 use serde::ser::SerializeMap;
110
111 let mut map = ser.serialize_map(Some(1))?;
112 map.serialize_entry(self.kind(), self.as_str())?;
113 map.end()
114 }
115}
116
117impl Ref {
118 pub fn all(reference: String) -> [Self; 3] {
120 [
121 Ref::Branch(reference.clone()),
122 Ref::Tag(reference.clone()),
123 Ref::Rev(reference),
124 ]
125 }
126
127 pub fn branch<R: Into<String>>(reference: R) -> Self {
129 Ref::Branch(reference.into())
130 }
131
132 pub fn tag<R: Into<String>>(reference: R) -> Self {
134 Ref::Tag(reference.into())
135 }
136
137 pub fn rev<R: Into<String>>(reference: R) -> Self {
139 Ref::Rev(reference.into())
140 }
141
142 #[inline]
144 pub fn master() -> Self {
145 Ref::branch("master")
146 }
147
148 #[inline]
150 pub fn as_str(&self) -> &str {
151 match self {
152 Self::Branch(r) | Self::Tag(r) | Self::Rev(r) => r
153 }
154 }
155
156 #[inline]
158 pub fn kind(&self) -> &'static str {
159 match self {
160 Self::Branch(_) => "branch",
161 Self::Tag(_) => "tag",
162 Self::Rev(_) => "rev",
163 }
164 }
165}