geonative_core/
dataset.rs1use std::sync::Arc;
22
23use crate::{Error, Feature, Result, Schema};
24
25pub trait Dataset {
28 fn layer_names(&self) -> Vec<String>;
30
31 fn open_layer<'a>(&'a self, name: &str) -> Result<Box<dyn Layer + 'a>>;
34}
35
36pub trait Layer {
39 fn name(&self) -> &str;
41
42 fn schema(&self) -> &Schema;
44
45 fn feature_count(&self) -> Option<i64>;
48
49 fn read<'a>(&'a self) -> Box<dyn Iterator<Item = Result<Feature>> + 'a>;
51}
52
53#[derive(Debug)]
57pub struct SingleLayerDataset<L: Layer> {
58 pub inner: Arc<L>,
61 pub name: String,
64}
65
66impl<L: Layer> SingleLayerDataset<L> {
67 pub fn new(layer: L) -> Self {
68 Self {
69 inner: Arc::new(layer),
70 name: "default".to_string(),
71 }
72 }
73
74 pub fn with_name(layer: L, name: impl Into<String>) -> Self {
75 Self {
76 inner: Arc::new(layer),
77 name: name.into(),
78 }
79 }
80}
81
82impl<L: Layer + 'static> Dataset for SingleLayerDataset<L> {
83 fn layer_names(&self) -> Vec<String> {
84 vec![self.name.clone()]
85 }
86
87 fn open_layer<'a>(&'a self, name: &str) -> Result<Box<dyn Layer + 'a>> {
88 if name == self.name {
89 Ok(Box::new(LayerRef(self.inner.as_ref())))
90 } else {
91 Err(Error::LayerNotFound(name.to_string()))
92 }
93 }
94}
95
96#[derive(Debug)]
98struct LayerRef<'a, L: Layer>(&'a L);
99
100impl<'a, L: Layer> Layer for LayerRef<'a, L> {
101 fn name(&self) -> &str {
102 self.0.name()
103 }
104 fn schema(&self) -> &Schema {
105 self.0.schema()
106 }
107 fn feature_count(&self) -> Option<i64> {
108 self.0.feature_count()
109 }
110 fn read<'b>(&'b self) -> Box<dyn Iterator<Item = Result<Feature>> + 'b> {
111 self.0.read()
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use crate::{Crs, FieldDef, GeomField, GeometryType, ValueType};
119
120 struct TestLayer {
122 name: String,
123 schema: Schema,
124 features: Vec<Feature>,
125 }
126
127 impl Layer for TestLayer {
128 fn name(&self) -> &str {
129 &self.name
130 }
131 fn schema(&self) -> &Schema {
132 &self.schema
133 }
134 fn feature_count(&self) -> Option<i64> {
135 Some(self.features.len() as i64)
136 }
137 fn read<'a>(&'a self) -> Box<dyn Iterator<Item = Result<Feature>> + 'a> {
138 Box::new(self.features.iter().cloned().map(Ok))
139 }
140 }
141
142 fn make_layer() -> TestLayer {
143 TestLayer {
144 name: "roads".into(),
145 schema: Schema::new(
146 vec![FieldDef::new("id", ValueType::Int32, false)],
147 Some(GeomField::new("geom", GeometryType::Point)),
148 Crs::Unknown,
149 ),
150 features: vec![
151 Feature::new(Some(1), None, vec![crate::Value::Int32(1)]),
152 Feature::new(Some(2), None, vec![crate::Value::Int32(2)]),
153 ],
154 }
155 }
156
157 #[test]
158 fn single_layer_dataset_exposes_one_layer() {
159 let ds = SingleLayerDataset::with_name(make_layer(), "default");
160 assert_eq!(ds.layer_names(), vec!["default"]);
161 let layer = ds.open_layer("default").unwrap();
162 assert_eq!(layer.feature_count(), Some(2));
163 }
164
165 #[test]
166 fn single_layer_dataset_rejects_wrong_name() {
167 let ds = SingleLayerDataset::new(make_layer());
168 assert!(ds.open_layer("nope").is_err());
169 }
170
171 #[test]
172 fn layer_read_iterator_yields_features() {
173 let layer = make_layer();
174 let v: Vec<_> = layer.read().collect::<Result<Vec<_>>>().unwrap();
175 assert_eq!(v.len(), 2);
176 }
177
178 #[test]
179 fn dataset_is_object_safe() {
180 fn _take_dataset(_: Box<dyn Dataset>) {}
182 let ds: Box<dyn Dataset> = Box::new(SingleLayerDataset::new(make_layer()));
183 _take_dataset(ds);
184 }
185}