hglib/commands/
outgoing.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 bookmarks: bool,
15    pub branch: &'a str,
16    pub limit: Option<u32>,
17    pub nomerges: bool,
18    pub subrepos: bool,
19}
20
21impl<'a> Default for Arg<'a> {
22    fn default() -> Self {
23        Self {
24            revrange: &[],
25            path: "",
26            force: false,
27            newest: false,
28            bookmarks: false,
29            branch: "",
30            limit: None,
31            nomerges: false,
32            subrepos: false,
33        }
34    }
35}
36
37impl<'a> Arg<'a> {
38    fn run(&self, client: &mut Client) -> Result<(Vec<u8>, i32), HglibError> {
39        runcommand!(
40            client,
41            "outgoing",
42            &[self.path],
43            "--template",
44            common::CHANGESETS_TEMPLATE,
45            "-r",
46            self.revrange,
47            "-f",
48            self.force,
49            "-n",
50            self.newest,
51            "-B",
52            self.bookmarks,
53            "-b",
54            self.branch,
55            "-l",
56            self.limit,
57            "-M",
58            self.nomerges,
59            "-S",
60            self.subrepos
61        )
62    }
63}
64
65#[derive(Debug, PartialEq)]
66pub struct Bookmark {
67    pub bookmark: String,
68    pub revision: String,
69}
70
71#[derive(Debug, PartialEq)]
72pub enum Outgoing {
73    Revisions(Vec<common::Revision>),
74    Bookmarks(Vec<Bookmark>),
75    Empty,
76}
77
78impl Client {
79    pub fn outgoing(&mut self, x: Arg) -> Result<Outgoing, HglibError> {
80        let data = match x.run(self) {
81            Ok(ret) => ret.0,
82            Err(e) => {
83                if e.code == 1 {
84                    return Ok(Outgoing::Empty);
85                } else {
86                    return Err(e);
87                }
88            }
89        };
90
91        let data = common::eatlines(&data, 2);
92        if x.bookmarks {
93            let mut res = Vec::new();
94            let mut tmp: &[u8] = &[];
95            let mut odd = false;
96            for chunk in data
97                .split(|c| *c == b' ' || *c == b'\n')
98                .filter(|&c| !c.is_empty())
99            {
100                if odd {
101                    res.push(Bookmark {
102                        bookmark: String::from_utf8(tmp.to_vec())?,
103                        revision: String::from_utf8(chunk.to_vec())?,
104                    });
105                    odd = false;
106                } else {
107                    tmp = chunk;
108                    odd = true;
109                }
110            }
111            Ok(Outgoing::Bookmarks(res))
112        } else {
113            Ok(Outgoing::Revisions(common::parserevs(data.to_vec())?))
114        }
115    }
116}