bbox_feature_server/
config.rs

1use bbox_core::config::{from_config_root_or_exit, ConfigError, DsPostgisCfg, NamedDatasourceCfg};
2use bbox_core::service::ServiceConfig;
3use clap::ArgMatches;
4use serde::Deserialize;
5
6#[derive(Deserialize, Default, Debug)]
7#[serde(default)]
8pub struct FeatureServiceCfg {
9    #[serde(rename = "datasource")]
10    pub datasources: Vec<NamedDatasourceCfg>,
11    #[serde(rename = "collections")]
12    pub auto_collections: CollectionsCfg,
13    #[serde(rename = "collection")]
14    pub collections: Vec<ConfiguredCollectionCfg>,
15}
16
17/// Collections with auto-detection
18#[derive(Deserialize, Default, Debug)]
19#[serde(default, deny_unknown_fields)]
20pub struct CollectionsCfg {
21    pub directory: Vec<DsFiledirCfg>,
22    pub postgis: Vec<DsPostgisCfg>,
23}
24
25#[derive(Deserialize, Debug)]
26#[serde(deny_unknown_fields)]
27pub struct DsFiledirCfg {
28    pub dir: String,
29}
30
31#[derive(Deserialize, Debug)]
32#[serde(deny_unknown_fields)]
33pub struct ConfiguredCollectionCfg {
34    pub name: String,
35    pub title: Option<String>,
36    pub description: Option<String>,
37    // extent: Option<CoreExtent>
38    #[serde(flatten)]
39    pub source: CollectionSourceCfg,
40}
41
42/// Collections with configuration
43#[derive(Deserialize, Debug)]
44#[serde(deny_unknown_fields)]
45pub enum CollectionSourceCfg {
46    #[serde(rename = "postgis")]
47    Postgis(PostgisCollectionCfg),
48    #[serde(rename = "gpkg")]
49    Gpkg(GpkgCollectionCfg),
50}
51
52#[derive(Deserialize, Default, Clone, Debug)]
53#[serde(deny_unknown_fields)]
54pub struct PostgisCollectionCfg {
55    /// Name of datasource.postgis config (Default: first with matching type)
56    pub datasource: Option<String>,
57    // maybe we should allow direct DS URLs?
58    // pub url: Option<String>,
59    pub table_schema: Option<String>,
60    pub table_name: Option<String>,
61    /// Custom SQL query
62    pub sql: Option<String>,
63    pub fid_field: Option<String>,
64    pub geometry_field: Option<String>,
65    //pub field_list: Option<Vec<String>>,
66    /// Field used for temporal filter expressions
67    pub temporal_field: Option<String>,
68    /// Field used for temporal end filter expressions
69    pub temporal_end_field: Option<String>,
70    /// Fields which can be used in filter expressions
71    #[serde(default)]
72    pub queryable_fields: Vec<String>,
73}
74
75#[derive(Deserialize, Default, Debug)]
76#[serde(deny_unknown_fields)]
77pub struct GpkgCollectionCfg {
78    /// Name of datasource.gpkg config (Default: first with matching type)
79    pub datasource: Option<String>,
80    pub table_name: Option<String>,
81    /// Custom SQL query
82    pub sql: Option<String>,
83    pub fid_field: Option<String>,
84    pub geometry_field: Option<String>,
85    //pub field_list: Option<Vec<String>>,
86}
87
88impl ServiceConfig for FeatureServiceCfg {
89    fn initialize(_cli: &ArgMatches) -> Result<Self, ConfigError> {
90        let cfg: FeatureServiceCfg = from_config_root_or_exit();
91        Ok(cfg)
92    }
93}
94
95impl CollectionsCfg {
96    #[allow(dead_code)]
97    pub fn from_path(path: &str) -> Self {
98        let mut cfg = CollectionsCfg::default();
99        cfg.directory.push(DsFiledirCfg {
100            dir: path.to_string(),
101        });
102        cfg
103    }
104}