]> git.lizzy.rs Git - rust.git/blob - src/librustc/ich/fingerprint.rs
Merge branch 'master' into issue-40006
[rust.git] / src / librustc / ich / fingerprint.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use rustc_serialize::{Encodable, Decodable, Encoder, Decoder};
12 use rustc_data_structures::stable_hasher;
13 use rustc_data_structures::ToHex;
14
15 const FINGERPRINT_LENGTH: usize = 16;
16
17 #[derive(Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Clone, Copy)]
18 pub struct Fingerprint(pub [u8; FINGERPRINT_LENGTH]);
19
20 impl Fingerprint {
21     #[inline]
22     pub fn zero() -> Fingerprint {
23         Fingerprint([0; FINGERPRINT_LENGTH])
24     }
25
26     pub fn from_smaller_hash(hash: u64) -> Fingerprint {
27         let mut result = Fingerprint::zero();
28         result.0[0] = (hash >>  0) as u8;
29         result.0[1] = (hash >>  8) as u8;
30         result.0[2] = (hash >> 16) as u8;
31         result.0[3] = (hash >> 24) as u8;
32         result.0[4] = (hash >> 32) as u8;
33         result.0[5] = (hash >> 40) as u8;
34         result.0[6] = (hash >> 48) as u8;
35         result.0[7] = (hash >> 56) as u8;
36         result
37     }
38
39     pub fn to_smaller_hash(&self) -> u64 {
40         ((self.0[0] as u64) <<  0) |
41         ((self.0[1] as u64) <<  8) |
42         ((self.0[2] as u64) << 16) |
43         ((self.0[3] as u64) << 24) |
44         ((self.0[4] as u64) << 32) |
45         ((self.0[5] as u64) << 40) |
46         ((self.0[6] as u64) << 48) |
47         ((self.0[7] as u64) << 56)
48     }
49
50     pub fn to_hex(&self) -> String {
51         self.0.to_hex()
52     }
53 }
54
55 impl Encodable for Fingerprint {
56     #[inline]
57     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
58         for &byte in &self.0 {
59             s.emit_u8(byte)?;
60         }
61         Ok(())
62     }
63 }
64
65 impl Decodable for Fingerprint {
66     #[inline]
67     fn decode<D: Decoder>(d: &mut D) -> Result<Fingerprint, D::Error> {
68         let mut result = Fingerprint([0u8; FINGERPRINT_LENGTH]);
69         for byte in &mut result.0 {
70             *byte = d.read_u8()?;
71         }
72         Ok(result)
73     }
74 }
75
76 impl ::std::fmt::Display for Fingerprint {
77     fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
78         for i in 0 .. self.0.len() {
79             if i > 0 {
80                 write!(formatter, "::")?;
81             }
82
83             write!(formatter, "{}", self.0[i])?;
84         }
85         Ok(())
86     }
87 }
88
89
90 impl stable_hasher::StableHasherResult for Fingerprint {
91     fn finish(mut hasher: stable_hasher::StableHasher<Self>) -> Self {
92         let mut fingerprint = Fingerprint::zero();
93         fingerprint.0.copy_from_slice(hasher.finalize());
94         fingerprint
95     }
96 }