hglib/commands/
incoming.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this file,
3// You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use super::common;
6use crate::client::{Client, HglibError, Runner};
7use crate::{runcommand, MkArg};
8
9pub struct Arg<'a> {
10    pub revrange: &'a [&'a str],
11    pub path: &'a str,
12    pub force: bool,
13    pub newest: bool,
14    pub bundle: &'a str,
15    pub bookmarks: bool,
16    pub branch: &'a str,
17    pub limit: Option<u32>,
18    pub nomerges: bool,
19    pub subrepos: bool,
20}
21
22impl<'a> Default for Arg<'a> {
23    fn default() -> Self {
24        Self {
25            revrange: &[],
26            path: "",
27            force: false,
28            newest: false,
29            bundle: "",
30            bookmarks: false,
31            branch: "",
32            limit: None,
33            nomerges: false,
34            subrepos: false,
35        }
36    }
37}
38
39impl<'a> Arg<'a> {
40    fn run(&self, client: &mut Client) -> Result<(Vec<u8>, i32), HglibError> {
41        runcommand!(
42            client,
43            "incoming",
44            &[self.path],
45            "--template",
46            common::CHANGESETS_TEMPLATE,
47            "-r",
48            self.revrange,
49            "-f",
50            self.force,
51            "-n",
52            self.newest,
53            "--bundle",
54            self.bundle,
55            "-B",
56            self.bookmarks,
57            "-b",
58            self.branch,
59            "-l",
60            self.limit,
61            "-M",
62            self.nomerges,
63            "-S",
64            self.subrepos
65        )
66    }
67}
68
69#[derive(Debug, PartialEq)]
70pub struct Bookmark {
71    pub bookmark: String,
72    pub revision: String,
73}
74
75#[derive(Debug, PartialEq)]
76pub enum Incoming {
77    Revisions(Vec<common::Revision>),
78    Bookmarks(Vec<Bookmark>),
79    Empty,
80}
81
82impl Client {
83    pub fn incoming(&mut self, x: Arg) -> Result<Incoming, HglibError> {
84        match x.run(self) {
85            Ok((data, _)) => {
86                if data.is_empty() {
87                    return Ok(Incoming::Empty);
88                }
89
90                let data = common::eatlines(&data, 2);
91                if x.bookmarks {
92                    let mut res = Vec::new();
93                    let mut tmp: &[u8] = &[];
94                    let mut odd = false;
95                    for chunk in data
96                        .split(|c| *c == b' ' || *c == b'\n')
97                        .filter(|&c| !c.is_empty())
98                    {
99                        if odd {
100                            res.push(Bookmark {
101                                bookmark: String::from_utf8(tmp.to_vec())?,
102                                revision: String::from_utf8(chunk.to_vec())?,
103                            });
104                            odd = false;
105                        } else {
106                            tmp = chunk;
107                            odd = true;
108                        }
109                    }
110                    Ok(Incoming::Bookmarks(res))
111                } else {
112                    Ok(Incoming::Revisions(common::parserevs(data.to_vec())?))
113                }
114            }
115            Err(err) => {
116                if err.code == 1 {
117                    Ok(Incoming::Empty)
118                } else {
119                    Err(err)
120                }
121            }
122        }
123    }
124}