1use std::cell::RefCell;
4use std::collections::{HashMap, HashSet};
5use std::error::Error;
6use std::fmt::{self, Display, Formatter};
7use std::rc::Rc;
8
9pub type PathSet = HashSet<String>;
11
12#[derive(Debug, Copy, Clone)]
17pub enum Change {
18 Added,
19 Deleted,
20 Modified,
21 Renamed{ percent_changed: u8},
22 Copied{ percent_changed: u8},
23}
24
25#[derive(Debug, Clone)]
27pub struct FileDelta {
28 pub change: Change,
30
31 pub path: String,
33
34 pub from: String,
37}
38
39#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
41pub struct SHA1 {
42 bytes: [u8; 20]
43}
44
45#[derive(Copy, Clone, Debug)]
46pub enum SHA1ParseError {
47 IncorrectLength,
48 InvalidHexadecimal
49}
50
51impl Error for SHA1ParseError {
52 fn description(&self) -> &str {
53 match *self {
54 SHA1ParseError::IncorrectLength => "String is not 40 characters long",
55 SHA1ParseError::InvalidHexadecimal => "String is not valid hexadecimal",
56 }
57 }
58}
59
60impl Display for SHA1ParseError {
61 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
62 self.description().fmt(f)
63 }
64}
65
66impl SHA1 {
67 pub fn parse(s: &str) -> Result<SHA1, SHA1ParseError> {
69 if s.len() != 40 { return Err(SHA1ParseError::IncorrectLength) }
70
71 let mut ret = SHA1::default();
72
73 for i in 0..20 {
74 let char_index = i * 2;
75 ret.bytes[i] = match u8::from_str_radix(&s[char_index .. char_index + 2], 16) {
76 Ok(b) => b,
77 _ => { return Err(SHA1ParseError::InvalidHexadecimal); },
78 };
79 }
80
81 Ok(ret)
82 }
83}
84
85impl Display for SHA1 {
86 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
87 for b in &self.bytes {
88 match write!(f, "{:02x}", b) {
89 Ok (()) => { },
90 err => { return err; }
91 };
92 }
93 Ok(())
94 }
95}
96
97impl Default for SHA1 {
98 fn default() -> SHA1 { SHA1{bytes: [0; 20]} }
99}
100
101pub type Link<T> = Rc<RefCell<T>>;
103
104pub struct HistoryNode<T> {
106 pub data: Option<Rc<T>>,
113
114 pub previous: Option<Link<HistoryNode<T>>>,
116}
117
118pub type HistoryTree<T> = HashMap<String, Link<HistoryNode<T>>>;