font_index/
shared_data.rs1use std::{io, fmt};
4use std::path::Path;
5use std::sync::{Arc, Weak};
6use std::time::SystemTime;
7
8enum Inner {
9 Mapped(memmap2::Mmap),
10 Memory(Vec<u8>),
11}
12
13impl Inner {
14 fn data(&self) -> &[u8] {
15 match self {
16 Self::Mapped(mmap) => &*mmap,
17 Self::Memory(vec) => &vec,
18 }
19 }
20}
21
22impl fmt::Debug for Inner {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 match self {
25 Self::Mapped(mmap) => write!(f, "{:?}", mmap),
26 Self::Memory(vec) => write!(f, "{:?}..", &vec[..50]),
27 }
28 }
29}
30
31#[derive(Clone, Debug)]
33#[repr(transparent)]
34pub struct SharedData {
35 inner: Arc<Inner>,
36}
37
38#[derive(Clone, Debug)]
40#[repr(transparent)]
41pub struct WeakSharedData {
42 inner: Weak<Inner>,
43}
44
45impl WeakSharedData {
46 pub fn upgrade(&self) -> Option<SharedData> {
48 Some(SharedData {
49 inner: self.inner.upgrade()?,
50 })
51 }
52}
53
54impl SharedData {
55 pub fn new(data: Vec<u8>) -> Self {
57 Self {
58 inner: Arc::new(Inner::Memory(data)),
59 }
60 }
61
62 pub fn from_file(
64 path: impl AsRef<Path>,
65 mmap: bool,
66 timestamp: Option<SystemTime>,
67 ) -> Result<Self, io::Error> {
68 let path = path.as_ref();
69 if let Some(timestamp) = timestamp {
70 let metadata = path.metadata()?;
71 let current_timestamp = metadata.modified()?;
72 if timestamp != current_timestamp {
73 return Err(io::Error::from(io::ErrorKind::InvalidData));
75 }
76 }
77 let inner = Arc::new(if mmap {
78 let file = std::fs::File::open(path)?;
79 let map = unsafe { memmap2::Mmap::map(&file)? };
80 Inner::Mapped(map)
81 } else {
82 let data = std::fs::read(path)?;
83 Inner::Memory(data)
84 });
85 Ok(Self { inner })
86 }
87
88 pub fn downgrade(&self) -> WeakSharedData {
90 WeakSharedData {
91 inner: Arc::downgrade(&self.inner),
92 }
93 }
94
95 pub fn as_bytes(&self) -> &[u8] {
97 self.inner.data()
98 }
99
100 pub fn strong_count(&self) -> usize {
102 Arc::strong_count(&self.inner)
103 }
104}
105
106impl std::ops::Deref for SharedData {
107 type Target = [u8];
108
109 fn deref(&self) -> &Self::Target {
110 self.inner.data()
111 }
112}
113
114impl AsRef<[u8]> for SharedData {
115 fn as_ref(&self) -> &[u8] {
116 self.inner.data()
117 }
118}