|
@@ -14,12 +14,13 @@ fn add_keys<E: Entity, IC: InterfaceCustomization>(
|
|
mut cmd: clap::Command,
|
|
mut cmd: clap::Command,
|
|
role: ValueRole,
|
|
role: ValueRole,
|
|
) -> clap::Command {
|
|
) -> clap::Command {
|
|
- struct UVisitor<'a, IC: InterfaceCustomization>(
|
|
|
|
|
|
+ struct UVisitor<'a, IC: InterfaceCustomization, E: Entity>(
|
|
&'a mut clap::Command,
|
|
&'a mut clap::Command,
|
|
ValueRole,
|
|
ValueRole,
|
|
- std::marker::PhantomData<IC>,
|
|
|
|
|
|
+ std::marker::PhantomData<(IC, E)>,
|
|
);
|
|
);
|
|
- impl<'a, IC: InterfaceCustomization> EntityPartVisitor for UVisitor<'a, IC> {
|
|
|
|
|
|
+ impl<'a, IC: InterfaceCustomization, E: Entity> EntityPartVisitor for UVisitor<'a, IC, E> {
|
|
|
|
+ type Entity = E;
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
if !IC::has_value_for(EP::Entity::entity_name(), EP::part_name(), self.1) {
|
|
if !IC::has_value_for(EP::Entity::entity_name(), EP::part_name(), self.1) {
|
|
let arg = clap::Arg::new(EP::part_name())
|
|
let arg = clap::Arg::new(EP::part_name())
|
|
@@ -30,7 +31,7 @@ fn add_keys<E: Entity, IC: InterfaceCustomization>(
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- <E::Keys as EntityPartList>::accept_part_visitor(&mut UVisitor::<IC>(
|
|
|
|
|
|
+ <E::Keys as EntityPartList>::accept_part_visitor(&mut UVisitor::<IC, E>(
|
|
&mut cmd,
|
|
&mut cmd,
|
|
role,
|
|
role,
|
|
Default::default(),
|
|
Default::default(),
|
|
@@ -43,13 +44,14 @@ fn collect_keys<E: Entity, IC: InterfaceCustomization>(
|
|
matches: &clap::ArgMatches,
|
|
matches: &clap::ArgMatches,
|
|
role: ValueRole,
|
|
role: ValueRole,
|
|
) -> Vec<EntityKey> {
|
|
) -> Vec<EntityKey> {
|
|
- struct UVisitor<'a, IC: InterfaceCustomization>(
|
|
|
|
|
|
+ struct UVisitor<'a, IC: InterfaceCustomization, E: Entity>(
|
|
&'a clap::ArgMatches,
|
|
&'a clap::ArgMatches,
|
|
&'a mut Vec<EntityKey>,
|
|
&'a mut Vec<EntityKey>,
|
|
ValueRole,
|
|
ValueRole,
|
|
- std::marker::PhantomData<IC>,
|
|
|
|
|
|
+ std::marker::PhantomData<(IC, E)>,
|
|
);
|
|
);
|
|
- impl<'a, IC: InterfaceCustomization> EntityPartVisitor for UVisitor<'a, IC> {
|
|
|
|
|
|
+ impl<'a, IC: InterfaceCustomization, E: Entity> EntityPartVisitor for UVisitor<'a, IC, E> {
|
|
|
|
+ type Entity = E;
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
if !IC::has_value_for(EP::Entity::entity_name(), EP::part_name(), self.2) {
|
|
if !IC::has_value_for(EP::Entity::entity_name(), EP::part_name(), self.2) {
|
|
self.1.push(EntityKey::UserInput(
|
|
self.1.push(EntityKey::UserInput(
|
|
@@ -69,7 +71,7 @@ fn collect_keys<E: Entity, IC: InterfaceCustomization>(
|
|
}
|
|
}
|
|
|
|
|
|
let mut key_values = vec![];
|
|
let mut key_values = vec![];
|
|
- <E::Keys as EntityPartList>::accept_part_visitor(&mut UVisitor::<IC>(
|
|
|
|
|
|
+ <E::Keys as EntityPartList>::accept_part_visitor(&mut UVisitor::<IC, E>(
|
|
matches,
|
|
matches,
|
|
&mut key_values,
|
|
&mut key_values,
|
|
role,
|
|
role,
|
|
@@ -128,13 +130,14 @@ impl<O: CLIObject> InterfaceVerb<O> {
|
|
.ok_or(clap::Error::new(clap::error::ErrorKind::MissingSubcommand))?;
|
|
.ok_or(clap::Error::new(clap::error::ErrorKind::MissingSubcommand))?;
|
|
|
|
|
|
// find the relevant relation
|
|
// find the relevant relation
|
|
- struct RelationFinder<'l, IC: InterfaceCustomization> {
|
|
|
|
|
|
+ struct RelationFinder<'l, IC: InterfaceCustomization, E: Entity> {
|
|
subcommand: &'l str,
|
|
subcommand: &'l str,
|
|
submatches: &'l clap::ArgMatches,
|
|
submatches: &'l clap::ArgMatches,
|
|
keys: &'l mut Vec<EntityKey>,
|
|
keys: &'l mut Vec<EntityKey>,
|
|
- _ghost: std::marker::PhantomData<IC>,
|
|
|
|
|
|
+ _ghost: std::marker::PhantomData<(IC, E)>,
|
|
}
|
|
}
|
|
- impl<'l, IC: InterfaceCustomization> EntityPartVisitor for RelationFinder<'l, IC> {
|
|
|
|
|
|
+ impl<'l, IC: InterfaceCustomization, E: Entity> EntityPartVisitor for RelationFinder<'l, IC, E> {
|
|
|
|
+ type Entity = E;
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
if EP::part_name() != self.subcommand {
|
|
if EP::part_name() != self.subcommand {
|
|
return;
|
|
return;
|
|
@@ -146,7 +149,7 @@ impl<O: CLIObject> InterfaceVerb<O> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- impl<'l, IC: InterfaceCustomization> EntityVisitor for RelationFinder<'l, IC> {
|
|
|
|
|
|
+ impl<'l, IC: InterfaceCustomization, OE: Entity> EntityVisitor for RelationFinder<'l, IC, OE> {
|
|
fn visit<E: Entity>(&mut self) {
|
|
fn visit<E: Entity>(&mut self) {
|
|
println!("\trelationfinder visiting entity {}", E::entity_name());
|
|
println!("\trelationfinder visiting entity {}", E::entity_name());
|
|
*self.keys = collect_keys::<E, IC>(self.submatches, ValueRole::AttachmentTarget);
|
|
*self.keys = collect_keys::<E, IC>(self.submatches, ValueRole::AttachmentTarget);
|
|
@@ -154,7 +157,7 @@ impl<O: CLIObject> InterfaceVerb<O> {
|
|
}
|
|
}
|
|
|
|
|
|
let mut remote_keys = vec![];
|
|
let mut remote_keys = vec![];
|
|
- O::accept_part_visitor(&mut RelationFinder::<IC> {
|
|
|
|
|
|
+ O::accept_part_visitor(&mut RelationFinder::<IC, O> {
|
|
subcommand,
|
|
subcommand,
|
|
submatches,
|
|
submatches,
|
|
keys: &mut remote_keys,
|
|
keys: &mut remote_keys,
|
|
@@ -210,14 +213,15 @@ impl<O: CLIObject> InterfaceVerb<O> {
|
|
}
|
|
}
|
|
|
|
|
|
/// helper type for attach and detach verbs
|
|
/// helper type for attach and detach verbs
|
|
-struct Attacher<'l, Error: CLIError> {
|
|
|
|
|
|
+struct Attacher<'l, Error: CLIError, E: Entity> {
|
|
do_attach: bool,
|
|
do_attach: bool,
|
|
relation: &'l str,
|
|
relation: &'l str,
|
|
remote_keys: Vec<String>,
|
|
remote_keys: Vec<String>,
|
|
err: Option<Error>,
|
|
err: Option<Error>,
|
|
|
|
+ _ghost: std::marker::PhantomData<E>,
|
|
}
|
|
}
|
|
|
|
|
|
-impl<'l, Error: CLIError> Attacher<'l, Error> {
|
|
|
|
|
|
+impl<'l, Error: CLIError, OE: Entity> Attacher<'l, Error, OE> {
|
|
fn do_operation<E: Entity>(&mut self, map: &impl AssocInterface<RemoteEntity = E>) {
|
|
fn do_operation<E: Entity>(&mut self, map: &impl AssocInterface<RemoteEntity = E>) {
|
|
match map
|
|
match map
|
|
.query_all()
|
|
.query_all()
|
|
@@ -252,7 +256,8 @@ impl<'l, Error: CLIError> Attacher<'l, Error> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-impl<'l, Error: CLIError> EntityPartVisitor for Attacher<'l, Error> {
|
|
|
|
|
|
+impl<'l, Error: CLIError, E: Entity> EntityPartVisitor for Attacher<'l, Error, E> {
|
|
|
|
+ type Entity = E;
|
|
fn visit_datum<EP: microrm::schema::entity::EntityPart>(&mut self, datum: &EP::Datum) {
|
|
fn visit_datum<EP: microrm::schema::entity::EntityPart>(&mut self, datum: &EP::Datum) {
|
|
if EP::part_name() != self.relation {
|
|
if EP::part_name() != self.relation {
|
|
return;
|
|
return;
|
|
@@ -262,7 +267,7 @@ impl<'l, Error: CLIError> EntityPartVisitor for Attacher<'l, Error> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-impl<'l, Error: CLIError> DatumDiscriminatorRef for Attacher<'l, Error> {
|
|
|
|
|
|
+impl<'l, Error: CLIError, OE: Entity> DatumDiscriminatorRef for Attacher<'l, Error, OE> {
|
|
fn visit_entity_id<E: Entity>(&mut self, _: &E::ID) {
|
|
fn visit_entity_id<E: Entity>(&mut self, _: &E::ID) {
|
|
unreachable!()
|
|
unreachable!()
|
|
}
|
|
}
|
|
@@ -359,6 +364,7 @@ impl<O: CLIObject, IC: InterfaceCustomization> ClapInterface<O, IC> {
|
|
relation,
|
|
relation,
|
|
remote_keys,
|
|
remote_keys,
|
|
err: None,
|
|
err: None,
|
|
|
|
+ _ghost: Default::default(),
|
|
};
|
|
};
|
|
outer_obj.accept_part_visitor_ref(&mut attacher);
|
|
outer_obj.accept_part_visitor_ref(&mut attacher);
|
|
|
|
|
|
@@ -405,6 +411,7 @@ impl<O: CLIObject, IC: InterfaceCustomization> ClapInterface<O, IC> {
|
|
relation,
|
|
relation,
|
|
remote_keys,
|
|
remote_keys,
|
|
err: None,
|
|
err: None,
|
|
|
|
+ _ghost: Default::default(),
|
|
};
|
|
};
|
|
outer_obj.accept_part_visitor_ref(&mut attacher);
|
|
outer_obj.accept_part_visitor_ref(&mut attacher);
|
|
|
|
|
|
@@ -446,8 +453,9 @@ impl<O: CLIObject, IC: InterfaceCustomization> ClapInterface<O, IC> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- struct AssocFieldWalker;
|
|
|
|
- impl EntityPartVisitor for AssocFieldWalker {
|
|
|
|
|
|
+ struct AssocFieldWalker<E: Entity>(std::marker::PhantomData<E>);
|
|
|
|
+ impl<E: Entity> EntityPartVisitor for AssocFieldWalker<E> {
|
|
|
|
+ type Entity = E;
|
|
fn visit_datum<EP: microrm::schema::entity::EntityPart>(
|
|
fn visit_datum<EP: microrm::schema::entity::EntityPart>(
|
|
&mut self,
|
|
&mut self,
|
|
datum: &EP::Datum,
|
|
datum: &EP::Datum,
|
|
@@ -485,7 +493,7 @@ impl<O: CLIObject, IC: InterfaceCustomization> ClapInterface<O, IC> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- obj.accept_part_visitor_ref(&mut AssocFieldWalker);
|
|
|
|
|
|
+ obj.accept_part_visitor_ref(&mut AssocFieldWalker(Default::default()));
|
|
}
|
|
}
|
|
InterfaceVerb::Extra(extra) => {
|
|
InterfaceVerb::Extra(extra) => {
|
|
O::run_extra_command(data, extra, query_ctx, insert_ctx)?;
|
|
O::run_extra_command(data, extra, query_ctx, insert_ctx)?;
|
|
@@ -497,11 +505,12 @@ impl<O: CLIObject, IC: InterfaceCustomization> ClapInterface<O, IC> {
|
|
fn make_relation_subcommands() -> impl Iterator<Item = clap::Command> {
|
|
fn make_relation_subcommands() -> impl Iterator<Item = clap::Command> {
|
|
let mut out = vec![];
|
|
let mut out = vec![];
|
|
|
|
|
|
- struct PartVisitor<'l, IC: InterfaceCustomization>(
|
|
|
|
|
|
+ struct PartVisitor<'l, IC: InterfaceCustomization, E: Entity>(
|
|
&'l mut Vec<clap::Command>,
|
|
&'l mut Vec<clap::Command>,
|
|
- std::marker::PhantomData<IC>,
|
|
|
|
|
|
+ std::marker::PhantomData<(IC, E)>,
|
|
);
|
|
);
|
|
- impl<'l, IC: InterfaceCustomization> EntityPartVisitor for PartVisitor<'l, IC> {
|
|
|
|
|
|
+ impl<'l, IC: InterfaceCustomization, E: Entity> EntityPartVisitor for PartVisitor<'l, IC, E> {
|
|
|
|
+ type Entity = E;
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
fn visit<EP: microrm::schema::entity::EntityPart>(&mut self) {
|
|
struct Discriminator<'l, IC: InterfaceCustomization>(
|
|
struct Discriminator<'l, IC: InterfaceCustomization>(
|
|
&'l mut Vec<clap::Command>,
|
|
&'l mut Vec<clap::Command>,
|
|
@@ -544,7 +553,7 @@ impl<O: CLIObject, IC: InterfaceCustomization> ClapInterface<O, IC> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- O::accept_part_visitor(&mut PartVisitor::<IC>(&mut out, Default::default()));
|
|
|
|
|
|
+ O::accept_part_visitor(&mut PartVisitor::<IC, O>(&mut out, Default::default()));
|
|
|
|
|
|
out.into_iter()
|
|
out.into_iter()
|
|
}
|
|
}
|