Skip to content

Commit

Permalink
CLI: 各 SinkProvider の情報を使って Sinkの一覧(ID、名前)を組む (#275)
Browse files Browse the repository at this point in the history
Nusamai CLI
でのSinkの選択において、SinkProviderが提供する情報を使ってSinkの一覧をうまく作るように変更する。いままではenum
のVariantsとして手書きで列挙していた。

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **新機能**
    - `GpkgSinkProvider` に複数のシンクプロバイダを統合した `SinkChoice` 構造体を追加しました。
    - `Args` 構造体をコメントを明確化して更新しました。
- 列挙型 `SinkChoice` を構造体に置き換え、動的なシンク選択処理のために `clap::ValueEnum` を実装しました。
    - より拡張性の高いために、`SinkChoice` 作成メソッドをループを使用してリファクタリングしました。

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
ciscorn authored Feb 14, 2024
1 parent f6d776e commit fb48e44
Show file tree
Hide file tree
Showing 17 changed files with 74 additions and 48 deletions.
2 changes: 1 addition & 1 deletion nusamai/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ serde = { version = "1.0.196", features = ["derive"] }
nusamai-plateau = { path = "../nusamai-plateau" }
nusamai-citygml = { path = "../nusamai-citygml" }
quick-xml = "0.31.0"
clap = { version = "4.5.0", features = ["derive"] }
clap = { version = "4.5.0", features = ["derive", "string"] }
thiserror = "1.0.57"
ctrlc = "3.4.2"
bincode = "1.3.3"
Expand Down
15 changes: 15 additions & 0 deletions nusamai/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,18 @@ pub mod pipeline;
pub mod sink;
pub mod source;
pub mod transformer;

pub static BUILTIN_SINKS: &[&dyn sink::DataSinkProvider] = &[
&sink::cesiumtiles::CesiumTilesSinkProvider {},
&sink::gpkg::GpkgSinkProvider {},
&sink::mvt::MVTSinkProvider {},
&sink::geojson::GeoJsonSinkProvider {},
&sink::geojson_transform_exp::GeoJsonTransformExpSinkProvider {},
&sink::czml::CzmlSinkProvider {},
&sink::gltf_poc::GltfPocSinkProvider {},
&sink::kml::KmlSinkProvider {},
&sink::ply::StanfordPlySinkProvider {},
&sink::serde::SerdeSinkProvider {},
&sink::shapefile::ShapefileSinkProvider {},
&sink::noop::NoopSinkProvider {},
];
79 changes: 38 additions & 41 deletions nusamai/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,39 @@
use std::env;
use std::sync::{Arc, Mutex};
use std::sync::{Arc, Mutex, OnceLock};

use clap::Parser;

use nusamai::pipeline::Canceller;
use nusamai::sink::{
cesiumtiles::CesiumTilesSinkProvider, czml::CzmlSinkProvider, geojson::GeoJsonSinkProvider,
geojson_transform_exp::GeoJsonTransformExpSinkProvider, gltf_poc::GltfPocSinkProvider,
gpkg::GpkgSinkProvider, kml::KmlSinkProvider, mvt::MVTSinkProvider, noop::NoopSinkProvider,
ply::StanfordPlySinkProvider, serde::SerdeSinkProvider, shapefile::ShapefileSinkProvider,
};

use nusamai::sink::{DataSink, DataSinkProvider};
use nusamai::source::citygml::CityGmlSourceProvider;
use nusamai::source::{DataSource, DataSourceProvider};
use nusamai::transformer::MultiThreadTransformer;
use nusamai::transformer::{NusamaiTransformBuilder, TransformBuilder};
use nusamai::BUILTIN_SINKS;
use nusamai_citygml::CityGmlElement;
use nusamai_plateau::models::TopLevelCityObject;

#[derive(clap::Parser)]
#[command(author, version, about, long_about = None)]
struct Args {
/// Specify path patterns to the input CityGML files
#[arg()]
file_patterns: Vec<String>,

/// Sink choice
/// Select the output format
#[arg(value_enum, long)]
sink: SinkChoice,

/// Output path
/// Specify the output path
#[arg(long)]
output: String,

/// Options for the source
/// Add an option for the input (CityGML)
#[arg(short = 'i', value_parser = parse_key_val)]
sourceopt: Vec<(String, String)>,

/// Options for the sink
/// Add an option for the output format
#[arg(short = 'o', value_parser = parse_key_val)]
sinkopt: Vec<(String, String)>,
}
Expand All @@ -49,39 +45,41 @@ fn parse_key_val(s: &str) -> Result<(String, String), String> {
Ok((s[..pos].into(), s[pos + 1..].into()))
}

#[derive(clap::ValueEnum, Clone)]
enum SinkChoice {
Noop,
Serde,
Geojson,
Gpkg,
Mvt,
GeojsonTransformExp,
#[clap(name = "3dtiles")]
CesiumTiles,
Shapefile,
Czml,
Ply,
KML,
GltfPoc,
#[derive(Clone)]
struct SinkChoice(String);

static SINK_CHOICE_VARIANTS: OnceLock<Vec<SinkChoice>> = OnceLock::new();

impl clap::ValueEnum for SinkChoice {
fn value_variants<'a>() -> &'a [Self] {
SINK_CHOICE_VARIANTS.get_or_init(|| {
BUILTIN_SINKS
.iter()
.map(|provider| Self(provider.info().id_name))
.collect()
});
SINK_CHOICE_VARIANTS.get().unwrap()
}

fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
BUILTIN_SINKS
.iter()
.find(|provider| provider.info().id_name == self.0)
.map(|provider| {
let info = provider.info();
clap::builder::PossibleValue::new(info.id_name).help(info.name)
})
}
}

impl SinkChoice {
fn create(&self) -> Box<dyn DataSinkProvider> {
match self {
SinkChoice::Noop => Box::new(NoopSinkProvider {}),
SinkChoice::Serde => Box::new(SerdeSinkProvider {}),
SinkChoice::Geojson => Box::new(GeoJsonSinkProvider {}),
SinkChoice::GeojsonTransformExp => Box::new(GeoJsonTransformExpSinkProvider {}),
SinkChoice::Gpkg => Box::new(GpkgSinkProvider {}),
SinkChoice::Mvt => Box::new(MVTSinkProvider {}),
SinkChoice::CesiumTiles => Box::new(CesiumTilesSinkProvider {}),
SinkChoice::Shapefile => Box::new(ShapefileSinkProvider {}),
SinkChoice::Czml => Box::new(CzmlSinkProvider {}),
SinkChoice::Ply => Box::new(StanfordPlySinkProvider {}),
SinkChoice::KML => Box::new(KmlSinkProvider {}),
SinkChoice::GltfPoc => Box::new(GltfPocSinkProvider {}),
fn create(&self) -> &dyn DataSinkProvider {
for &provider in nusamai::BUILTIN_SINKS {
if self.0 == provider.info().id_name {
return provider;
}
}
panic!("Unknown sink choice: {:?}", self.0);
}
}

Expand All @@ -95,7 +93,6 @@ fn main() {
// output path
let mut args = Args::parse();
args.sinkopt.push(("@output".into(), args.output.clone()));

args
};

Expand Down
3 changes: 2 additions & 1 deletion nusamai/src/sink/cesiumtiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ pub struct CesiumTilesSinkProvider {}
impl DataSinkProvider for CesiumTilesSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
name: "Vector Tiles (MVT)".to_string(),
id_name: "3dtiles".to_string(),
name: "Cesium 3D Tiles".to_string(),
}
}

Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/czml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct CzmlSinkProvider {}
impl DataSinkProvider for CzmlSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "czml".to_string(),
name: "CZML".to_string(),
}
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/geojson/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub struct GeoJsonSinkProvider {}
impl DataSinkProvider for GeoJsonSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "geojson".to_string(),
name: "GeoJSON".to_string(),
}
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/geojson_transform_exp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub struct GeoJsonTransformExpSinkProvider {}
impl DataSinkProvider for GeoJsonTransformExpSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "geojson-tf-exp".to_string(),
name: "GeoJSON".to_string(),
}
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/gltf_poc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct GltfPocSinkProvider {}
impl DataSinkProvider for GltfPocSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "gltf-poc".to_string(),
name: "glTF".to_string(),
}
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/gpkg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct GpkgSinkProvider {}
impl DataSinkProvider for GpkgSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "gpkg".to_string(),
name: "GeoPackage".to_string(),
}
}
Expand Down
3 changes: 2 additions & 1 deletion nusamai/src/sink/kml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ pub struct KmlSinkProvider {}
impl DataSinkProvider for KmlSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
name: "kml".to_string(),
id_name: "kml".to_string(),
name: "KML".to_string(),
}
}

Expand Down
5 changes: 3 additions & 2 deletions nusamai/src/sink/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ pub mod geojson;
pub mod geojson_transform_exp;
pub mod gltf_poc;
pub mod gpkg;
pub mod kml;
pub mod mvt;
pub mod noop;
pub mod ply;
pub mod serde;
pub mod shapefile;
pub mod kml;

use nusamai_citygml::schema::Schema;

Expand All @@ -20,10 +20,11 @@ use crate::pipeline::{Feedback, PipelineError, Receiver};
use crate::transformer;

pub struct SinkInfo {
pub id_name: String,
pub name: String,
}

pub trait DataSinkProvider {
pub trait DataSinkProvider: Sync {
/// Gets basic information about the sink.
fn info(&self) -> SinkInfo;

Expand Down
3 changes: 2 additions & 1 deletion nusamai/src/sink/mvt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ pub struct MVTSinkProvider {}
impl DataSinkProvider for MVTSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
name: "Vector Tiles (MVT)".to_string(),
id_name: "mvt".to_string(),
name: "Mapbox Vector Tiles (MVT)".to_string(),
}
}

Expand Down
3 changes: 2 additions & 1 deletion nusamai/src/sink/noop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ impl DataSinkProvider for NoopSinkProvider {

fn info(&self) -> SinkInfo {
SinkInfo {
name: "No-op".to_string(),
id_name: "noop".to_string(),
name: "No Output".to_string(),
}
}

Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/ply/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct StanfordPlySinkProvider {}
impl DataSinkProvider for StanfordPlySinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "ply".to_string(),
name: "Stanford PLY".to_string(),
}
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/serde/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub struct SerdeSinkProvider {}
impl DataSinkProvider for SerdeSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "serde".to_string(),
name: "Serde (bincode)".to_string(),
}
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/src/sink/shapefile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub struct ShapefileSinkProvider {}
impl DataSinkProvider for ShapefileSinkProvider {
fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "shapefile".to_string(),
name: "Shapefile".to_string(),
}
}
Expand Down
1 change: 1 addition & 0 deletions nusamai/tests/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl DataSinkProvider for DummySinkProvider {

fn info(&self) -> SinkInfo {
SinkInfo {
id_name: "dummy".to_string(),
name: "Dummy Sink".to_string(),
}
}
Expand Down

0 comments on commit fb48e44

Please sign in to comment.