bonsaidb_local/cli/
schema.rs1use std::str::FromStr;
2
3use bonsaidb_core::connection::{AsyncStorageConnection, StorageConnection};
4use bonsaidb_core::schema::{
5 CollectionName, InvalidNameError, SchemaName, SchemaSummary, ViewName,
6};
7use clap::Parser;
8
9#[derive(Parser, Debug)]
11pub struct Command {
12 pub name: Option<SchemaName>,
14
15 pub item: Option<CollectionOrView>,
17}
18
19impl Command {
20 pub fn execute<SC: StorageConnection>(self, storage: &SC) -> Result<(), crate::Error> {
22 let schemas = storage.list_available_schemas()?;
23 self.handle_schema_command(schemas)
24 }
25
26 pub async fn execute_async<SC: AsyncStorageConnection>(
28 self,
29 storage: &SC,
30 ) -> Result<(), crate::Error> {
31 let schemas = storage.list_available_schemas().await?;
32 self.handle_schema_command(schemas)
33 }
34
35 fn handle_schema_command(self, schemas: Vec<SchemaSummary>) -> Result<(), crate::Error> {
36 if let Some(name) = self.name {
37 let Some(schema) = schemas.into_iter().find(|s| s.name == name) else {
38 return Err(crate::Error::Core(
39 bonsaidb_core::Error::SchemaNotRegistered(name),
40 ));
41 };
42
43 if let Some(item) = self.item {
44 match item {
45 CollectionOrView::View(view) => {
46 let Some(collection) = schema.collection(&view.collection) else {
47 return Err(crate::Error::Core(
48 bonsaidb_core::Error::CollectionNotFound,
49 ));
50 };
51 let Some(view) = collection.view(&view) else {
52 return Err(crate::Error::Core(bonsaidb_core::Error::ViewNotFound));
53 };
54 println!("Version: {}", view.version);
55 println!("Policy: {}", view.policy);
56 }
57 CollectionOrView::Collection(collection) => {
58 let Some(collection) = schema.collection(&collection) else {
59 return Err(crate::Error::Core(
60 bonsaidb_core::Error::CollectionNotFound,
61 ));
62 };
63 let mut views = collection.views().collect::<Vec<_>>();
64 views.sort_by(|v1, v2| v1.name.cmp(&v2.name));
65 for view in views {
66 println!("{}", view.name);
67 }
68 }
69 }
70 } else {
71 print_collection_list(&schema);
72 }
73 } else if let Some(item) = self.item {
74 eprintln!("missing `schema` for inspecting {item:?}");
75 std::process::exit(-1);
76 } else {
77 print_schema_list(schemas);
78 }
79 Ok(())
80 }
81}
82
83fn print_schema_list(mut schemas: Vec<SchemaSummary>) {
84 schemas.sort_by(|s1, s2| s1.name.cmp(&s2.name));
85
86 for schema in schemas {
87 println!("{}", schema.name);
88 }
89}
90
91fn print_collection_list(schema: &SchemaSummary) {
92 let mut collections = schema.collections().collect::<Vec<_>>();
93 collections.sort_by(|c1, c2| c1.name.cmp(&c2.name));
94
95 for collection in collections {
96 println!("{}", collection.name);
97 }
98}
99
100#[derive(Debug, Clone)]
102pub enum CollectionOrView {
103 View(ViewName),
105 Collection(CollectionName),
107}
108
109impl FromStr for CollectionOrView {
110 type Err = InvalidNameError;
111
112 fn from_str(s: &str) -> Result<Self, Self::Err> {
113 if let Ok(view) = ViewName::from_str(s) {
114 Ok(Self::View(view))
115 } else {
116 CollectionName::from_str(s).map(Self::Collection)
117 }
118 }
119}