Skip to main content

harmos_domain/operations/common/
direction.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10// One Stream Direction Of An Operation: `Stream<T>` Carries Items Of `T`;
11// `NoStream` Is The Uninhabited Item Of A Direction The Operation Does Not Use.
12
13/* === Modules === */
14
15/* === Re-Exports === */
16
17/* === Imports === */
18
19// Standard Library Imports
20use std::any::TypeId;
21use std::marker::PhantomData;
22
23// Third Party Imports
24
25// Local Imports
26use crate::schema::Described;
27use crate::schema::declaration::Definition;
28use crate::schema::graph::Field;
29use crate::{MemorySize, MessageError};
30
31/* === Constants === */
32
33/* === Macros === */
34
35/* === Type Aliases === */
36
37/* === Structs === */
38
39pub struct Stream<T>(PhantomData<fn() -> T>);
40
41/* === Enums === */
42
43#[derive(Clone, Copy, Debug, PartialEq, Eq)]
44pub enum NoStream {}
45
46/* === Traits === */
47
48pub trait Direction: Send + Sync + 'static {
49    type Item: crate::Portable;
50    const STREAMED: bool;
51
52    fn schema() -> Option<Definition> {
53        Self::STREAMED.then_some(<Self::Item as Described>::DEFINITION)
54    }
55
56    fn item_type() -> Option<TypeId> {
57        Self::STREAMED.then(TypeId::of::<Self::Item>)
58    }
59}
60
61/* === Implementations === */
62
63impl<T: crate::Portable> Direction for Stream<T> {
64    type Item = T;
65    const STREAMED: bool = true;
66}
67
68impl Direction for NoStream {
69    type Item = NoStream;
70    const STREAMED: bool = false;
71}
72
73impl Described for NoStream {
74    const NAME: &'static str = "harmos::no_stream";
75    const FIELDS: &'static [Field<Definition>] = &[];
76    const MARKER: &'static [u8] = &crate::schema::declaration::encode::<
77        { crate::schema::declaration::encoded_len(Self::NAME, Self::FIELDS) },
78    >(Self::NAME, Self::FIELDS);
79}
80
81impl MemorySize for NoStream {
82    fn memory_size(&self) -> usize {
83        match *self {}
84    }
85}
86
87impl crate::__private::PostcardValue for NoStream {
88    fn write(&self, _: &mut Vec<u8>) {
89        match *self {}
90    }
91    fn size(&self) -> usize {
92        match *self {}
93    }
94    fn memory(_: &mut crate::__private::PostcardReader<'_>) -> Result<usize, MessageError> {
95        Err(absent())
96    }
97    fn read(_: &mut crate::__private::PostcardReader<'_>) -> Result<Self, MessageError> {
98        Err(absent())
99    }
100}
101
102/* === Public Functions === */
103
104// The Item Types An Operation Streams, Input Then Output.
105pub fn item_types<O: super::OperationDeclaration>() -> (Option<TypeId>, Option<TypeId>) {
106    (<O::Input as Direction>::item_type(), <O::Output as Direction>::item_type())
107}
108
109/* === Private Functions === */
110
111fn absent() -> MessageError {
112    MessageError::borrowed("the operation streams no items in this direction")
113}
114
115/* === Tests === */