luct_core/tiling/
data_tile.rs1use crate::tiling::index_to_url;
2use std::num::NonZeroU8;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct DataTileId {
6 index: u64,
7 partial: Option<NonZeroU8>,
8}
9
10impl DataTileId {
11 pub fn from_index(index: u64, tree_height: u64) -> Option<Self> {
15 let tile_width = 256;
16
17 let index = index / tile_width;
19
20 let tile_end = (index + 1) * tile_width;
22 let partial = if tile_end < tree_height {
23 None
24 } else {
25 let partial: u8 = (tree_height % tile_width).try_into().unwrap();
26 Some(NonZeroU8::new(partial).unwrap())
27 };
28
29 Some(Self { index, partial })
30 }
31
32 pub fn as_url(&self) -> String {
33 let index_url = index_to_url(self.index);
34
35 match self.partial {
36 Some(partial) => format!("tile/data/{}.p/{}", index_url, partial),
37 None => format!("tile/data/{}", index_url),
38 }
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct DataTile {
44 id: DataTileId,
45 data: Vec<u8>,
46}
47
48#[cfg(test)]
49mod test {
50 use super::*;
51
52 #[test]
53 fn as_url() {
54 assert_eq!(&data_tile_id(1, None).as_url(), "tile/data/001");
55 assert_eq!(
56 &data_tile_id(10987654321, None).as_url(),
57 "tile/data/x010/x987/x654/321"
58 );
59 assert_eq!(
60 &data_tile_id(1234, Some(128)).as_url(),
61 "tile/data/x001/234.p/128"
62 );
63 }
64
65 #[test]
66 fn into_data_tile_id() {
67 assert_eq!(
68 DataTileId::from_index(4, 70000).unwrap(),
69 data_tile_id(0, None)
70 );
71 assert_eq!(
72 DataTileId::from_index(270, 70000).unwrap(),
73 data_tile_id(1, None)
74 );
75 assert_eq!(
76 DataTileId::from_index(69950, 70000).unwrap(),
77 data_tile_id(273, Some(112))
78 );
79 }
80
81 fn data_tile_id(index: u64, partial: Option<u8>) -> DataTileId {
82 DataTileId {
83 index,
84 partial: partial.map(|partial| NonZeroU8::new(partial).unwrap()),
85 }
86 }
87}