##// END OF EJS Templates
rust-utils: add docstrings and doctests for utils.rs...
Raphaël Gomès -
r42816:95113d70 default draft
parent child Browse files
Show More
@@ -1,105 +1,105 b''
1 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
1 // Copyright 2018 Georges Racinet <gracinet@anybox.fr>
2 //
2 //
3 // This software may be used and distributed according to the terms of the
3 // This software may be used and distributed according to the terms of the
4 // GNU General Public License version 2 or any later version.
4 // GNU General Public License version 2 or any later version.
5 mod ancestors;
5 mod ancestors;
6 pub mod dagops;
6 pub mod dagops;
7 pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors};
7 pub use ancestors::{AncestorsIterator, LazyAncestors, MissingAncestors};
8 mod dirstate;
8 mod dirstate;
9 pub mod discovery;
9 pub mod discovery;
10 pub mod testing; // unconditionally built, for use from integration tests
10 pub mod testing; // unconditionally built, for use from integration tests
11 pub use dirstate::{
11 pub use dirstate::{
12 dirs_multiset::DirsMultiset,
12 dirs_multiset::DirsMultiset,
13 parsers::{pack_dirstate, parse_dirstate},
13 parsers::{pack_dirstate, parse_dirstate},
14 CopyVec, CopyVecEntry, DirsIterable, DirstateEntry, DirstateParents,
14 CopyVec, CopyVecEntry, DirsIterable, DirstateEntry, DirstateParents,
15 DirstateVec,
15 DirstateVec,
16 };
16 };
17 mod filepatterns;
17 mod filepatterns;
18 mod utils;
18 pub mod utils;
19
19
20 pub use filepatterns::{
20 pub use filepatterns::{
21 build_single_regex, read_pattern_file, PatternSyntax, PatternTuple,
21 build_single_regex, read_pattern_file, PatternSyntax, PatternTuple,
22 };
22 };
23
23
24 /// Mercurial revision numbers
24 /// Mercurial revision numbers
25 ///
25 ///
26 /// As noted in revlog.c, revision numbers are actually encoded in
26 /// As noted in revlog.c, revision numbers are actually encoded in
27 /// 4 bytes, and are liberally converted to ints, whence the i32
27 /// 4 bytes, and are liberally converted to ints, whence the i32
28 pub type Revision = i32;
28 pub type Revision = i32;
29
29
30 /// Marker expressing the absence of a parent
30 /// Marker expressing the absence of a parent
31 ///
31 ///
32 /// Independently of the actual representation, `NULL_REVISION` is guaranteed
32 /// Independently of the actual representation, `NULL_REVISION` is guaranteed
33 /// to be smaller that all existing revisions.
33 /// to be smaller that all existing revisions.
34 pub const NULL_REVISION: Revision = -1;
34 pub const NULL_REVISION: Revision = -1;
35
35
36 /// Same as `mercurial.node.wdirrev`
36 /// Same as `mercurial.node.wdirrev`
37 ///
37 ///
38 /// This is also equal to `i32::max_value()`, but it's better to spell
38 /// This is also equal to `i32::max_value()`, but it's better to spell
39 /// it out explicitely, same as in `mercurial.node`
39 /// it out explicitely, same as in `mercurial.node`
40 pub const WORKING_DIRECTORY_REVISION: Revision = 0x7fffffff;
40 pub const WORKING_DIRECTORY_REVISION: Revision = 0x7fffffff;
41
41
42 /// The simplest expression of what we need of Mercurial DAGs.
42 /// The simplest expression of what we need of Mercurial DAGs.
43 pub trait Graph {
43 pub trait Graph {
44 /// Return the two parents of the given `Revision`.
44 /// Return the two parents of the given `Revision`.
45 ///
45 ///
46 /// Each of the parents can be independently `NULL_REVISION`
46 /// Each of the parents can be independently `NULL_REVISION`
47 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError>;
47 fn parents(&self, rev: Revision) -> Result<[Revision; 2], GraphError>;
48 }
48 }
49
49
50 pub type LineNumber = usize;
50 pub type LineNumber = usize;
51
51
52 #[derive(Clone, Debug, PartialEq)]
52 #[derive(Clone, Debug, PartialEq)]
53 pub enum GraphError {
53 pub enum GraphError {
54 ParentOutOfRange(Revision),
54 ParentOutOfRange(Revision),
55 WorkingDirectoryUnsupported,
55 WorkingDirectoryUnsupported,
56 }
56 }
57
57
58 #[derive(Clone, Debug, PartialEq)]
58 #[derive(Clone, Debug, PartialEq)]
59 pub enum DirstateParseError {
59 pub enum DirstateParseError {
60 TooLittleData,
60 TooLittleData,
61 Overflow,
61 Overflow,
62 CorruptedEntry(String),
62 CorruptedEntry(String),
63 }
63 }
64
64
65 #[derive(Debug, PartialEq)]
65 #[derive(Debug, PartialEq)]
66 pub enum DirstatePackError {
66 pub enum DirstatePackError {
67 CorruptedEntry(String),
67 CorruptedEntry(String),
68 CorruptedParent,
68 CorruptedParent,
69 BadSize(usize, usize),
69 BadSize(usize, usize),
70 }
70 }
71
71
72 #[derive(Debug, PartialEq)]
72 #[derive(Debug, PartialEq)]
73 pub enum DirstateMapError {
73 pub enum DirstateMapError {
74 PathNotFound(Vec<u8>),
74 PathNotFound(Vec<u8>),
75 EmptyPath,
75 EmptyPath,
76 }
76 }
77
77
78 impl From<std::io::Error> for DirstatePackError {
78 impl From<std::io::Error> for DirstatePackError {
79 fn from(e: std::io::Error) -> Self {
79 fn from(e: std::io::Error) -> Self {
80 DirstatePackError::CorruptedEntry(e.to_string())
80 DirstatePackError::CorruptedEntry(e.to_string())
81 }
81 }
82 }
82 }
83
83
84 impl From<std::io::Error> for DirstateParseError {
84 impl From<std::io::Error> for DirstateParseError {
85 fn from(e: std::io::Error) -> Self {
85 fn from(e: std::io::Error) -> Self {
86 DirstateParseError::CorruptedEntry(e.to_string())
86 DirstateParseError::CorruptedEntry(e.to_string())
87 }
87 }
88 }
88 }
89
89
90 #[derive(Debug)]
90 #[derive(Debug)]
91 pub enum PatternError {
91 pub enum PatternError {
92 UnsupportedSyntax(String),
92 UnsupportedSyntax(String),
93 }
93 }
94
94
95 #[derive(Debug)]
95 #[derive(Debug)]
96 pub enum PatternFileError {
96 pub enum PatternFileError {
97 IO(std::io::Error),
97 IO(std::io::Error),
98 Pattern(PatternError, LineNumber),
98 Pattern(PatternError, LineNumber),
99 }
99 }
100
100
101 impl From<std::io::Error> for PatternFileError {
101 impl From<std::io::Error> for PatternFileError {
102 fn from(e: std::io::Error) -> Self {
102 fn from(e: std::io::Error) -> Self {
103 PatternFileError::IO(e)
103 PatternFileError::IO(e)
104 }
104 }
105 }
105 }
@@ -1,45 +1,76 b''
1 pub mod files;
1 pub mod files;
2
2
3 /// Replaces the `from` slice with the `to` slice inside the `buf` slice.
4 ///
5 /// # Examples
6 ///
7 /// ```
8 /// use crate::hg::utils::replace_slice;
9 /// let mut line = b"I hate writing tests!".to_vec();
10 /// replace_slice(&mut line, b"hate", b"love");
11 /// assert_eq!(
12 /// line,
13 /// b"I love writing tests!".to_vec()
14 ///);
15 ///
16 /// ```
3 pub fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T])
17 pub fn replace_slice<T>(buf: &mut [T], from: &[T], to: &[T])
4 where
18 where
5 T: Clone + PartialEq,
19 T: Clone + PartialEq,
6 {
20 {
7 if buf.len() < from.len() || from.len() != to.len() {
21 assert_eq!(from.len(), to.len());
22 if buf.len() < from.len() {
8 return;
23 return;
9 }
24 }
10 for i in 0..=buf.len() - from.len() {
25 for i in 0..=buf.len() - from.len() {
11 if buf[i..].starts_with(from) {
26 if buf[i..].starts_with(from) {
12 buf[i..(i + from.len())].clone_from_slice(to);
27 buf[i..(i + from.len())].clone_from_slice(to);
13 }
28 }
14 }
29 }
15 }
30 }
16
31
17 pub trait SliceExt {
32 pub trait SliceExt {
33 fn trim_end(&self) -> &Self;
34 fn trim_start(&self) -> &Self;
18 fn trim(&self) -> &Self;
35 fn trim(&self) -> &Self;
19 fn trim_end(&self) -> &Self;
20 }
36 }
21
37
22 fn is_not_whitespace(c: &u8) -> bool {
38 fn is_not_whitespace(c: &u8) -> bool {
23 !(*c as char).is_whitespace()
39 !(*c as char).is_whitespace()
24 }
40 }
25
41
26 impl SliceExt for [u8] {
42 impl SliceExt for [u8] {
27 fn trim(&self) -> &[u8] {
28 if let Some(first) = self.iter().position(is_not_whitespace) {
29 if let Some(last) = self.iter().rposition(is_not_whitespace) {
30 &self[first..last + 1]
31 } else {
32 unreachable!();
33 }
34 } else {
35 &[]
36 }
37 }
38 fn trim_end(&self) -> &[u8] {
43 fn trim_end(&self) -> &[u8] {
39 if let Some(last) = self.iter().rposition(is_not_whitespace) {
44 if let Some(last) = self.iter().rposition(is_not_whitespace) {
40 &self[..last + 1]
45 &self[..last + 1]
41 } else {
46 } else {
42 &[]
47 &[]
43 }
48 }
44 }
49 }
50 fn trim_start(&self) -> &[u8] {
51 if let Some(first) = self.iter().position(is_not_whitespace) {
52 &self[first..]
53 } else {
54 &[]
55 }
56 }
57
58 /// ```
59 /// use hg::utils::SliceExt;
60 /// assert_eq!(
61 /// b" to trim ".trim(),
62 /// b"to trim"
63 /// );
64 /// assert_eq!(
65 /// b"to trim ".trim(),
66 /// b"to trim"
67 /// );
68 /// assert_eq!(
69 /// b" to trim".trim(),
70 /// b"to trim"
71 /// );
72 /// ```
73 fn trim(&self) -> &[u8] {
74 self.trim_start().trim_end()
75 }
45 }
76 }
General Comments 0
You need to be logged in to leave comments. Login now