1use crate::core::Adr;
4use crate::wiki::{github::GitHubWiki, gitlab::GitLabWiki};
5use crate::Error;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum WikiPlatform {
10 GitHub,
12 GitLab,
14}
15
16impl std::fmt::Display for WikiPlatform {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 Self::GitHub => write!(f, "github"),
20 Self::GitLab => write!(f, "gitlab"),
21 }
22 }
23}
24
25#[derive(Debug, Clone)]
27pub struct WikiConfig {
28 pub platform: WikiPlatform,
30 pub repository: String,
32 pub token: Option<String>,
34 pub base_url: Option<String>,
36}
37
38impl WikiConfig {
39 #[must_use]
41 pub fn new(platform: WikiPlatform, repository: impl Into<String>) -> Self {
42 Self {
43 platform,
44 repository: repository.into(),
45 token: None,
46 base_url: None,
47 }
48 }
49
50 #[must_use]
52 pub fn with_token(mut self, token: impl Into<String>) -> Self {
53 self.token = Some(token.into());
54 self
55 }
56
57 #[must_use]
59 pub fn with_base_url(mut self, url: impl Into<String>) -> Self {
60 self.base_url = Some(url.into());
61 self
62 }
63}
64
65#[derive(Debug)]
67pub struct WikiService {
68 config: WikiConfig,
69}
70
71impl WikiService {
72 #[must_use]
74 pub fn new(config: WikiConfig) -> Self {
75 Self { config }
76 }
77
78 pub fn push(&self, adr: &Adr) -> Result<(), Error> {
84 match self.config.platform {
85 WikiPlatform::GitHub => {
86 let parts: Vec<&str> = self.config.repository.split('/').collect();
87 if parts.len() != 2 {
88 return Err(Error::WikiError {
89 message: format!(
90 "Invalid GitHub repository format: {}",
91 self.config.repository
92 ),
93 });
94 }
95 let wiki = GitHubWiki::new(parts[0], parts[1]);
96 wiki.push(adr)
97 },
98 WikiPlatform::GitLab => {
99 let wiki = GitLabWiki::new(&self.config.repository);
100 wiki.push(adr)
101 },
102 }
103 }
104
105 pub fn pull(&self, id: &str) -> Result<Adr, Error> {
111 match self.config.platform {
112 WikiPlatform::GitHub => {
113 let parts: Vec<&str> = self.config.repository.split('/').collect();
114 if parts.len() != 2 {
115 return Err(Error::WikiError {
116 message: format!(
117 "Invalid GitHub repository format: {}",
118 self.config.repository
119 ),
120 });
121 }
122 let wiki = GitHubWiki::new(parts[0], parts[1]);
123 wiki.pull(id)
124 },
125 WikiPlatform::GitLab => {
126 let wiki = GitLabWiki::new(&self.config.repository);
127 wiki.pull(id)
128 },
129 }
130 }
131
132 pub fn sync(&self, adrs: &[Adr]) -> Result<SyncResult, Error> {
138 let mut result = SyncResult::default();
139
140 for adr in adrs {
141 match self.push(adr) {
142 Ok(()) => result.pushed += 1,
143 Err(e) => {
144 result.errors.push(format!("{}: {e}", adr.id));
145 },
146 }
147 }
148
149 Ok(result)
150 }
151}
152
153#[derive(Debug, Default)]
155pub struct SyncResult {
156 pub pushed: usize,
158 pub pulled: usize,
160 pub errors: Vec<String>,
162}