Skip to main content

breezyshim/
tags.rs

1//! Revision tags
2use crate::error::Error;
3use crate::revisionid::RevisionId;
4use pyo3::intern;
5use pyo3::prelude::*;
6use std::collections::{HashMap, HashSet};
7
8/// Represents a collection of revision tags.
9///
10/// Tags allow associating human-readable names with specific revision IDs.
11/// This struct provides methods to manage and query these tags.
12pub struct Tags(Py<PyAny>);
13
14impl From<Py<PyAny>> for Tags {
15    fn from(obj: Py<PyAny>) -> Self {
16        Tags(obj)
17    }
18}
19
20impl Tags {
21    /// Get a mapping from revision IDs to sets of tags.
22    ///
23    /// # Returns
24    ///
25    /// A HashMap mapping each revision ID to a set of tag names that point to it,
26    /// or an error if the operation fails
27    pub fn get_reverse_tag_dict(
28        &self,
29    ) -> Result<HashMap<RevisionId, HashSet<String>>, crate::error::Error> {
30        Python::attach(|py| self.0.call_method0(py, "get_reverse_tag_dict")?.extract(py))
31            .map_err(Into::into)
32    }
33
34    /// Get a mapping from tag names to revision IDs.
35    ///
36    /// # Returns
37    ///
38    /// A HashMap mapping each tag name to the revision ID it points to,
39    /// or an error if the operation fails
40    pub fn get_tag_dict(&self) -> Result<HashMap<String, RevisionId>, crate::error::Error> {
41        Python::attach(|py| {
42            self.0
43                .call_method0(py, intern!(py, "get_tag_dict"))?
44                .extract(py)
45        })
46        .map_err(Into::into)
47    }
48
49    /// Look up a revision ID by tag name.
50    ///
51    /// # Arguments
52    ///
53    /// * `tag` - The tag name to look up
54    ///
55    /// # Returns
56    ///
57    /// The revision ID the tag points to, or an error if the tag doesn't exist
58    pub fn lookup_tag(&self, tag: &str) -> Result<RevisionId, Error> {
59        Ok(Python::attach(|py| {
60            self.0.call_method1(py, "lookup_tag", (tag,))?.extract(py)
61        })?)
62    }
63
64    /// Check if a tag exists.
65    ///
66    /// # Arguments
67    ///
68    /// * `tag` - The tag name to check
69    ///
70    /// # Returns
71    ///
72    /// `true` if the tag exists, `false` otherwise
73    pub fn has_tag(&self, tag: &str) -> bool {
74        Python::attach(|py| {
75            self.0
76                .call_method1(py, "has_tag", (tag,))
77                .unwrap()
78                .extract(py)
79                .unwrap()
80        })
81    }
82
83    /// Set a tag to point to a specific revision.
84    ///
85    /// # Arguments
86    ///
87    /// * `tag` - The tag name to set
88    /// * `revision_id` - The revision ID the tag should point to
89    ///
90    /// # Returns
91    ///
92    /// `Ok(())` on success, or an error if the operation fails
93    pub fn set_tag(&self, tag: &str, revision_id: &RevisionId) -> Result<(), Error> {
94        Python::attach(|py| {
95            self.0
96                .call_method1(py, "set_tag", (tag, revision_id.clone()))
97        })?;
98        Ok(())
99    }
100
101    /// Delete a tag.
102    ///
103    /// # Arguments
104    ///
105    /// * `tag` - The tag name to delete
106    ///
107    /// # Returns
108    ///
109    /// `Ok(())` on success, or an error if the operation fails
110    pub fn delete_tag(&self, tag: &str) -> Result<(), Error> {
111        Python::attach(|py| self.0.call_method1(py, "delete_tag", (tag,)))?;
112        Ok(())
113    }
114}