diff --git a/api/schema b/api/schema index 2406e77..aa00650 160000 --- a/api/schema +++ b/api/schema @@ -1 +1 @@ -Subproject commit 2406e77fb9fd2ce3d6e183742521a5d9c9cf77af +Subproject commit aa006507c48ac734fd09d524d0c84736b0147338 diff --git a/api/src/schema/general_capnp.rs b/api/src/schema/general_capnp.rs index 221cd7f..68c0a18 100644 --- a/api/src/schema/general_capnp.rs +++ b/api/src/schema/general_capnp.rs @@ -296,3 +296,194 @@ pub mod key_value_pair { pub const TYPE_ID: u64 = 0xfb54_3b21_ce63_7bf1; } } + +pub mod optional { /* T */ + pub use self::Which::{Nothing,Just}; + + #[derive(Copy, Clone)] + pub struct Owned { + _phantom: ::core::marker::PhantomData + } + impl <'a, T> ::capnp::traits::Owned<'a> for Owned where T: for<'c> ::capnp::traits::Owned<'c> { type Reader = Reader<'a, T>; type Builder = Builder<'a, T>; } + impl <'a, T> ::capnp::traits::OwnedStruct<'a> for Owned where T: for<'c> ::capnp::traits::Owned<'c> { type Reader = Reader<'a, T>; type Builder = Builder<'a, T>; } + impl ::capnp::traits::Pipelined for Owned where T: for<'c> ::capnp::traits::Owned<'c> { type Pipeline = Pipeline; } + + #[derive(Clone, Copy)] + pub struct Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + reader: ::capnp::private::layout::StructReader<'a>, + _phantom: ::core::marker::PhantomData + } + + impl <'a,T> ::capnp::traits::HasTypeId for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,T> ::capnp::traits::FromStructReader<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,T> { + Reader { reader, _phantom: ::core::marker::PhantomData, } + } + } + + impl <'a,T> ::capnp::traits::FromPointerReader<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructReader::new(reader.get_struct(default)?)) + } + } + + impl <'a,T> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,T> ::capnp::traits::Imbue<'a> for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,T> Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + pub fn reborrow(&self) -> Reader<'_,T> { + Reader { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + pub fn has_just(&self) -> bool { + if self.reader.get_data_field::(0) != 1 { return false; } + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn which(self) -> ::core::result::Result, ::capnp::NotInSchema> { + match self.reader.get_data_field::(0) { + 0 => { + ::core::result::Result::Ok(Nothing( + () + )) + } + 1 => { + ::core::result::Result::Ok(Just( + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + )) + } + x => ::core::result::Result::Err(::capnp::NotInSchema(x)) + } + } + } + + pub struct Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + builder: ::capnp::private::layout::StructBuilder<'a>, + _phantom: ::core::marker::PhantomData + } + impl <'a,T> ::capnp::traits::HasStructSize for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + #[inline] + fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE } + } + impl <'a,T> ::capnp::traits::HasTypeId for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,T> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, T> { + Builder { builder, _phantom: ::core::marker::PhantomData, } + } + } + + impl <'a,T> ::capnp::traits::ImbueMut<'a> for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,T> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,T> { + ::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE)) + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructBuilder::new(builder.get_struct(_private::STRUCT_SIZE, default)?)) + } + } + + impl <'a,T> ::capnp::traits::SetPointerBuilder for Reader<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,T>, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,T> Builder<'a,T> where T: for<'c> ::capnp::traits::Owned<'c> { + pub fn into_reader(self) -> Reader<'a,T> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + pub fn reborrow(&mut self) -> Builder<'_,T> { + Builder { .. *self } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,T> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.into_reader().total_size() + } + #[inline] + pub fn set_nothing(&mut self, _value: ()) { + self.builder.set_data_field::(0, 0); + } + #[inline] + pub fn initn_just(self, length: u32) -> >::Builder { + self.builder.set_data_field::(0, 1); + ::capnp::any_pointer::Builder::new(self.builder.get_pointer_field(0)).initn_as(length) + } + #[inline] + pub fn set_just(&mut self, value: >::Reader) -> ::capnp::Result<()> { + self.builder.set_data_field::(0, 1); + ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.get_pointer_field(0), value, false) + } + #[inline] + pub fn init_just(self, ) -> >::Builder { + self.builder.set_data_field::(0, 1); + ::capnp::any_pointer::Builder::new(self.builder.get_pointer_field(0)).init_as() + } + pub fn has_just(&self) -> bool { + if self.builder.get_data_field::(0) != 1 { return false; } + !self.builder.get_pointer_field(0).is_null() + } + #[inline] + pub fn which(self) -> ::core::result::Result, ::capnp::NotInSchema> { + match self.builder.get_data_field::(0) { + 0 => { + ::core::result::Result::Ok(Nothing( + () + )) + } + 1 => { + ::core::result::Result::Ok(Just( + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + )) + } + x => ::core::result::Result::Err(::capnp::NotInSchema(x)) + } + } + } + + pub struct Pipeline { + _typeless: ::capnp::any_pointer::Pipeline, + _phantom: ::core::marker::PhantomData + } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline { + Pipeline { _typeless: typeless, _phantom: ::core::marker::PhantomData, } + } + } + impl Pipeline where T: ::capnp::traits::Pipelined, ::Pipeline: ::capnp::capability::FromTypelessPipeline { + } + mod _private { + use capnp::private::layout; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 1 }; + pub const TYPE_ID: u64 = 0xd77e_cca2_05b0_6927; + } + pub enum Which { + Nothing(()), + Just(A0), + } + pub type WhichReader<'a,T> = Which<::capnp::Result<>::Reader>>; + pub type WhichBuilder<'a,T> = Which<::capnp::Result<>::Builder>>; +} diff --git a/api/src/schema/machinesystem_capnp.rs b/api/src/schema/machinesystem_capnp.rs index 459e648..d002d58 100644 --- a/api/src/schema/machinesystem_capnp.rs +++ b/api/src/schema/machinesystem_capnp.rs @@ -136,9 +136,9 @@ pub mod machine_system { pub type GetMachineListParams<> = ::capnp::capability::Params; pub type GetMachineListResults<> = ::capnp::capability::Results; pub type GetMachineParams<> = ::capnp::capability::Params; - pub type GetMachineResults<> = ::capnp::capability::Results; + pub type GetMachineResults<> = ::capnp::capability::Results>; pub type GetMachineURNParams<> = ::capnp::capability::Params; - pub type GetMachineURNResults<> = ::capnp::capability::Results; + pub type GetMachineURNResults<> = ::capnp::capability::Results>; pub struct Client { pub client: ::capnp::capability::Client, @@ -185,10 +185,10 @@ pub mod machine_system { pub fn get_machine_list_request(&self) -> ::capnp::capability::Request { self.client.new_call(_private::TYPE_ID, 0, None) } - pub fn get_machine_request(&self) -> ::capnp::capability::Request { + pub fn get_machine_request(&self) -> ::capnp::capability::Request> { self.client.new_call(_private::TYPE_ID, 1, None) } - pub fn get_machine_u_r_n_request(&self) -> ::capnp::capability::Request { + pub fn get_machine_u_r_n_request(&self) -> ::capnp::capability::Request> { self.client.new_call(_private::TYPE_ID, 2, None) } } diff --git a/bffhd/capnp/machine.rs b/bffhd/capnp/machine.rs index 70ab2d4..b25c231 100644 --- a/bffhd/capnp/machine.rs +++ b/bffhd/capnp/machine.rs @@ -2,12 +2,14 @@ use crate::resources::modules::fabaccess::{ArchivedStatus, Status}; use crate::resources::Resource; use crate::session::SessionHandle; use api::machine_capnp::machine::{ + self, admin, admin::Server as AdminServer, check, check::Server as CheckServer, in_use as inuse, in_use::Server as InUseServer, info, info::Server as InfoServer, manage, manage::Server as ManageServer, use_, use_::Server as UseServer, - Builder, MachineState, + MachineState, }; +use api::general_capnp::optional; use capnp::capability::Promise; use capnp_rpc::pry; use crate::capnp::user::User; @@ -23,68 +25,73 @@ impl Machine { Self { session, resource } } - pub fn build_into(self, mut builder: Builder) { - if self.resource.visible(&self.session) { - - builder.set_id(self.resource.get_id()); - builder.set_name(self.resource.get_name()); - if let Some(ref desc) = self.resource.get_description().description { - builder.set_description(desc); - } - if let Some(ref wiki) = self.resource.get_description().wiki { - builder.set_wiki(wiki); - } - if let Some(ref category) = self.resource.get_description().category { - builder.set_category(category); - } - builder.set_urn(&format!("urn:fabaccess:resource:{}", self.resource.get_id())); - - { - let user = self.session.get_user_ref(); - let state = self.resource.get_state_ref(); - let state = state.as_ref(); - - if self.session.has_write(&self.resource) && match &state.inner.state { - ArchivedStatus::Free => true, - ArchivedStatus::Reserved(reserver) if reserver == &user => true, - _ => false, - } { - builder.set_use(capnp_rpc::new_client(self.clone())); - } - - if self.session.has_manage(&self.resource) { - builder.set_manage(capnp_rpc::new_client(self.clone())); - } - - // TODO: admin perm - - let s = match &state.inner.state { - ArchivedStatus::Free => MachineState::Free, - ArchivedStatus::Disabled => MachineState::Disabled, - ArchivedStatus::Blocked(_) => MachineState::Blocked, - ArchivedStatus::InUse(owner) => { - if owner == &user { - builder.set_inuse(capnp_rpc::new_client(self.clone())); - } - MachineState::InUse - }, - ArchivedStatus::Reserved(_) => MachineState::Reserved, - ArchivedStatus::ToCheck(_) => MachineState::ToCheck, - }; - if self.session.has_read(&self.resource) { - builder.set_state(s); - } - } - - builder.set_info(capnp_rpc::new_client(self)); + pub fn build_into(self, mut builder: machine::Builder) { + builder.set_id(self.resource.get_id()); + builder.set_name(self.resource.get_name()); + if let Some(ref desc) = self.resource.get_description().description { + builder.set_description(desc); } + if let Some(ref wiki) = self.resource.get_description().wiki { + builder.set_wiki(wiki); + } + if let Some(ref category) = self.resource.get_description().category { + builder.set_category(category); + } + builder.set_urn(&format!("urn:fabaccess:resource:{}", self.resource.get_id())); + + { + let user = self.session.get_user_ref(); + let state = self.resource.get_state_ref(); + let state = state.as_ref(); + + if self.session.has_write(&self.resource) && match &state.inner.state { + ArchivedStatus::Free => true, + ArchivedStatus::Reserved(reserver) if reserver == &user => true, + _ => false, + } { + builder.set_use(capnp_rpc::new_client(self.clone())); + } + + if self.session.has_manage(&self.resource) { + builder.set_manage(capnp_rpc::new_client(self.clone())); + } + + // TODO: admin perm + + let s = match &state.inner.state { + ArchivedStatus::Free => MachineState::Free, + ArchivedStatus::Disabled => MachineState::Disabled, + ArchivedStatus::Blocked(_) => MachineState::Blocked, + ArchivedStatus::InUse(owner) => { + if owner == &user { + builder.set_inuse(capnp_rpc::new_client(self.clone())); + } + MachineState::InUse + }, + ArchivedStatus::Reserved(_) => MachineState::Reserved, + ArchivedStatus::ToCheck(_) => MachineState::ToCheck, + }; + if self.session.has_read(&self.resource) { + builder.set_state(s); + } + } + + builder.set_info(capnp_rpc::new_client(self)); } /// Builds a machine into the given builder. Re - pub fn build(session: SessionHandle, resource: Resource, builder: Builder) { + pub fn build(session: SessionHandle, resource: Resource, builder: machine::Builder) { let this = Self::new(session.clone(), resource.clone()); this.build_into(builder) } + + pub fn optional_build(session: SessionHandle, resource: Resource, builder: optional::Builder) { + let this = Self::new(session.clone(), resource.clone()); + if this.resource.visible(&session) { + let mut builder = builder.init_just(); + this.build_into(builder); + } + } } impl InfoServer for Machine { diff --git a/bffhd/capnp/machinesystem.rs b/bffhd/capnp/machinesystem.rs index 52607fb..e261451 100644 --- a/bffhd/capnp/machinesystem.rs +++ b/bffhd/capnp/machinesystem.rs @@ -54,7 +54,7 @@ impl info::Server for Machines { if let Some(resource) = self.resources.get_by_id(id) { let builder = result.get(); - Machine::build(self.session.clone(), resource.clone(), builder); + Machine::optional_build(self.session.clone(), resource.clone(), builder); } Promise::ok(()) @@ -70,7 +70,7 @@ impl info::Server for Machines { if let Some(resource) = self.resources.get_by_urn(urn) { let builder = result.get(); - Machine::build(self.session.clone(), resource.clone(), builder); + Machine::optional_build(self.session.clone(), resource.clone(), builder); } Promise::ok(())