Refactor, replace by generic impl
This commit is contained in:
@@ -1,10 +1,20 @@
|
||||
use crate::numops::NumOps;
|
||||
use crate::streams::{Collectable, Collector, ToJsonBytes, ToJsonResult};
|
||||
use crate::{
|
||||
ts_offs_from_abs, Appendable, FilterFittingInside, Fits, FitsInside, FrameTypeStaticSYC, IsoDateTime, NewEmpty,
|
||||
RangeOverlapInfo, ReadPbv, ReadableFromFile, Sitemty, SitemtyFrameType, SubFrId, TimeBinnableDyn, TimeBinnableType,
|
||||
TimeBinnableTypeAggregator, TimeBinned, TimeBinnerDyn, TimeBins, WithLen,
|
||||
};
|
||||
use crate::ts_offs_from_abs;
|
||||
use crate::Appendable;
|
||||
use crate::FilterFittingInside;
|
||||
use crate::Fits;
|
||||
use crate::FitsInside;
|
||||
use crate::FrameTypeInnerStatic;
|
||||
use crate::IsoDateTime;
|
||||
use crate::ReadPbv;
|
||||
use crate::ReadableFromFile;
|
||||
use crate::Sitemty;
|
||||
use crate::SubFrId;
|
||||
use crate::TimeBinnableDyn;
|
||||
use crate::{NewEmpty, RangeOverlapInfo, WithLen};
|
||||
use crate::{TimeBinnableType, TimeBinnableTypeAggregator};
|
||||
use crate::{TimeBinned, TimeBinnerDyn, TimeBins};
|
||||
use chrono::{TimeZone, Utc};
|
||||
use err::Error;
|
||||
use netpod::log::*;
|
||||
@@ -28,22 +38,13 @@ pub struct MinMaxAvgDim0Bins<NTY> {
|
||||
pub avgs: Vec<f32>,
|
||||
}
|
||||
|
||||
impl<NTY> FrameTypeStaticSYC for MinMaxAvgDim0Bins<NTY>
|
||||
impl<NTY> FrameTypeInnerStatic for MinMaxAvgDim0Bins<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = crate::MIN_MAX_AVG_DIM_0_BINS_FRAME_TYPE_ID + NTY::SUB;
|
||||
}
|
||||
|
||||
impl<NTY> SitemtyFrameType for MinMaxAvgDim0Bins<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> fmt::Debug for MinMaxAvgDim0Bins<NTY>
|
||||
where
|
||||
NTY: fmt::Debug,
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
use crate::numops::NumOps;
|
||||
use crate::pulse_offs_from_abs;
|
||||
use crate::streams::{Collectable, Collector, ToJsonBytes, ToJsonResult};
|
||||
use crate::ts_offs_from_abs;
|
||||
use crate::waveevents::WaveEvents;
|
||||
use crate::{
|
||||
pulse_offs_from_abs, ts_offs_from_abs, Appendable, FilterFittingInside, Fits, FitsInside, FrameTypeStaticSYC,
|
||||
IsoDateTime, NewEmpty, RangeOverlapInfo, ReadPbv, ReadableFromFile, Sitemty, SitemtyFrameType, SubFrId,
|
||||
TimeBinnableDyn, TimeBinnableType, TimeBinnableTypeAggregator, TimeBinned, TimeBins, WithLen,
|
||||
};
|
||||
use crate::Appendable;
|
||||
use crate::FilterFittingInside;
|
||||
use crate::FrameTypeInnerStatic;
|
||||
use crate::IsoDateTime;
|
||||
use crate::RangeOverlapInfo;
|
||||
use crate::ReadableFromFile;
|
||||
use crate::TimeBinnableDyn;
|
||||
use crate::TimeBinnableType;
|
||||
use crate::TimeBinnableTypeAggregator;
|
||||
use crate::TimeBins;
|
||||
use crate::{Fits, FitsInside, NewEmpty, ReadPbv, Sitemty, SubFrId, TimeBinned, WithLen};
|
||||
use chrono::{TimeZone, Utc};
|
||||
use err::Error;
|
||||
use netpod::log::*;
|
||||
@@ -27,22 +35,13 @@ pub struct MinMaxAvgDim1Bins<NTY> {
|
||||
pub avgs: Vec<Option<Vec<f32>>>,
|
||||
}
|
||||
|
||||
impl<NTY> FrameTypeStaticSYC for MinMaxAvgDim1Bins<NTY>
|
||||
impl<NTY> FrameTypeInnerStatic for MinMaxAvgDim1Bins<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = crate::MIN_MAX_AVG_DIM_1_BINS_FRAME_TYPE_ID + NTY::SUB;
|
||||
}
|
||||
|
||||
impl<NTY> SitemtyFrameType for MinMaxAvgDim1Bins<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> fmt::Debug for MinMaxAvgDim1Bins<NTY>
|
||||
where
|
||||
NTY: fmt::Debug,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::binnedevents::XBinnedEvents;
|
||||
use crate::plainevents::PlainEvents;
|
||||
use crate::{Appendable, Clearable, PushableIndex, SitemtyFrameType, WithLen, WithTimestamps};
|
||||
use crate::{Appendable, Clearable, FrameTypeInnerDyn, PushableIndex, WithLen, WithTimestamps};
|
||||
use netpod::{AggKind, HasScalarType, HasShape, ScalarType, Shape};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -10,7 +10,7 @@ pub enum EventsItem {
|
||||
XBinnedEvents(XBinnedEvents),
|
||||
}
|
||||
|
||||
impl SitemtyFrameType for EventsItem {
|
||||
impl FrameTypeInnerDyn for EventsItem {
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
crate::EVENTS_ITEM_FRAME_TYPE_ID
|
||||
}
|
||||
|
||||
@@ -216,27 +216,35 @@ impl SubFrId for BoolNum {
|
||||
const SUB: u32 = 0x0e;
|
||||
}
|
||||
|
||||
// To be implemented by the data containers, i.e. the T's in Sitemty<T>, e.g. ScalarEvents.
|
||||
// TODO rename this, since it is misleading because it is not meanto to be implemented by Sitemty.
|
||||
pub trait SitemtyFrameType {
|
||||
// Required for any inner type of Sitemty.
|
||||
pub trait FrameTypeInnerStatic {
|
||||
const FRAME_TYPE_ID: u32;
|
||||
}
|
||||
|
||||
// To be implemented by the T of Sitemty<T>, e.g. ScalarEvents.
|
||||
pub trait FrameTypeInnerDyn {
|
||||
// TODO check actual usage of this
|
||||
fn frame_type_id(&self) -> u32;
|
||||
}
|
||||
|
||||
impl<T> FrameTypeInnerDyn for T
|
||||
where
|
||||
T: FrameTypeInnerStatic,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeInnerStatic>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
pub trait FrameTypeStatic {
|
||||
const FRAME_TYPE_ID: u32;
|
||||
}
|
||||
|
||||
// Required for any inner type of Sitemty.
|
||||
pub trait FrameTypeStaticSYC {
|
||||
const FRAME_TYPE_ID: u32;
|
||||
}
|
||||
|
||||
impl<T> FrameTypeStatic for Sitemty<T>
|
||||
where
|
||||
T: FrameTypeStaticSYC,
|
||||
T: FrameTypeInnerStatic,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = <T as FrameTypeStaticSYC>::FRAME_TYPE_ID;
|
||||
const FRAME_TYPE_ID: u32 = <T as FrameTypeInnerStatic>::FRAME_TYPE_ID;
|
||||
}
|
||||
|
||||
// Framable trait objects need some inspection to handle the supposed-to-be common Err ser format:
|
||||
@@ -266,10 +274,10 @@ where
|
||||
|
||||
impl<T> FrameType for Sitemty<T>
|
||||
where
|
||||
T: FrameTypeStaticSYC,
|
||||
T: FrameTypeInnerStatic,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<T as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
<T as FrameTypeInnerStatic>::FRAME_TYPE_ID
|
||||
}
|
||||
|
||||
fn is_err(&self) -> bool {
|
||||
@@ -287,13 +295,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl SitemtyFrameType for Box<dyn TimeBinned> {
|
||||
impl FrameTypeInnerDyn for Box<dyn TimeBinned> {
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
self.as_time_binnable_dyn().frame_type_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl SitemtyFrameType for Box<dyn EventsDyn> {
|
||||
impl FrameTypeInnerDyn for Box<dyn EventsDyn> {
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
self.as_time_binnable_dyn().frame_type_id()
|
||||
}
|
||||
@@ -303,11 +311,11 @@ pub trait Framable {
|
||||
fn make_frame(&self) -> Result<BytesMut, Error>;
|
||||
}
|
||||
|
||||
pub trait FramableInner: erased_serde::Serialize + SitemtyFrameType + Send {
|
||||
pub trait FramableInner: erased_serde::Serialize + FrameTypeInnerDyn + Send {
|
||||
fn _dummy(&self);
|
||||
}
|
||||
|
||||
impl<T: erased_serde::Serialize + SitemtyFrameType + Send> FramableInner for T {
|
||||
impl<T: erased_serde::Serialize + FrameTypeInnerDyn + Send> FramableInner for T {
|
||||
fn _dummy(&self) {}
|
||||
}
|
||||
|
||||
@@ -317,7 +325,7 @@ erased_serde::serialize_trait_object!(TimeBinned);
|
||||
|
||||
impl<T> Framable for Sitemty<T>
|
||||
where
|
||||
T: Sized + serde::Serialize + SitemtyFrameType,
|
||||
T: Sized + serde::Serialize + FrameTypeInnerDyn,
|
||||
{
|
||||
fn make_frame(&self) -> Result<BytesMut, Error> {
|
||||
match self {
|
||||
@@ -351,7 +359,7 @@ pub trait FrameDecodable: FrameTypeStatic + DeserializeOwned {
|
||||
|
||||
impl<T> FrameDecodable for Sitemty<T>
|
||||
where
|
||||
T: FrameTypeStaticSYC + DeserializeOwned,
|
||||
T: FrameTypeInnerStatic + DeserializeOwned,
|
||||
{
|
||||
fn from_error(e: err::Error) -> Self {
|
||||
Err(e)
|
||||
@@ -373,7 +381,7 @@ where
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct EventQueryJsonStringFrame(pub String);
|
||||
|
||||
impl FrameTypeStaticSYC for EventQueryJsonStringFrame {
|
||||
impl FrameTypeInnerStatic for EventQueryJsonStringFrame {
|
||||
const FRAME_TYPE_ID: u32 = EVENT_QUERY_JSON_STRING_FRAME;
|
||||
}
|
||||
|
||||
@@ -495,7 +503,7 @@ pub trait TimeBinnableType:
|
||||
+ Serialize
|
||||
+ DeserializeOwned
|
||||
+ ReadableFromFile
|
||||
+ FrameTypeStaticSYC
|
||||
+ FrameTypeInnerStatic
|
||||
{
|
||||
type Output: TimeBinnableType;
|
||||
type Aggregator: TimeBinnableTypeAggregator<Input = Self, Output = Self::Output> + Send + Unpin;
|
||||
@@ -508,14 +516,14 @@ pub trait TimeBinnableType:
|
||||
// TODO should not require Sync!
|
||||
// TODO SitemtyFrameType is already supertrait of FramableInner.
|
||||
pub trait TimeBinnableDyn:
|
||||
std::fmt::Debug + FramableInner + SitemtyFrameType + WithLen + RangeOverlapInfo + Any + Sync + Send + 'static
|
||||
std::fmt::Debug + FramableInner + FrameTypeInnerDyn + WithLen + RangeOverlapInfo + Any + Sync + Send + 'static
|
||||
{
|
||||
fn time_binner_new(&self, edges: Vec<u64>, do_time_weight: bool) -> Box<dyn TimeBinnerDyn>;
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
pub trait TimeBinnableDynStub:
|
||||
std::fmt::Debug + FramableInner + SitemtyFrameType + WithLen + RangeOverlapInfo + Any + Sync + Send + 'static
|
||||
std::fmt::Debug + FramableInner + FrameTypeInnerDyn + WithLen + RangeOverlapInfo + Any + Sync + Send + 'static
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@ use crate::numops::NumOps;
|
||||
use crate::streams::{Collectable, Collector};
|
||||
use crate::{
|
||||
pulse_offs_from_abs, ts_offs_from_abs, Appendable, ByteEstimate, Clearable, EventAppendable, EventsDyn,
|
||||
FilterFittingInside, Fits, FitsInside, FrameTypeStaticSYC, NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv,
|
||||
ReadableFromFile, SitemtyFrameType, TimeBinnableDyn, TimeBinnableType, TimeBinnableTypeAggregator, TimeBinnerDyn,
|
||||
WithLen, WithTimestamps,
|
||||
FilterFittingInside, Fits, FitsInside, FrameTypeInnerStatic, NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv,
|
||||
ReadableFromFile, TimeBinnableDyn, TimeBinnableType, TimeBinnableTypeAggregator, TimeBinnerDyn, WithLen,
|
||||
WithTimestamps,
|
||||
};
|
||||
use err::Error;
|
||||
use netpod::log::*;
|
||||
@@ -52,22 +52,13 @@ impl<NTY> ScalarEvents<NTY> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> FrameTypeStaticSYC for ScalarEvents<NTY>
|
||||
impl<NTY> FrameTypeInnerStatic for ScalarEvents<NTY>
|
||||
where
|
||||
NTY: NumOps,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = crate::EVENTS_0D_FRAME_TYPE_ID + NTY::SUB;
|
||||
}
|
||||
|
||||
impl<NTY> SitemtyFrameType for ScalarEvents<NTY>
|
||||
where
|
||||
NTY: NumOps,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> ScalarEvents<NTY> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::streams::{Collectable, Collector};
|
||||
use crate::{
|
||||
ts_offs_from_abs, Appendable, ByteEstimate, Clearable, EventAppendable, FilterFittingInside, Fits, FitsInside,
|
||||
FrameTypeStaticSYC, NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile, SitemtyFrameType,
|
||||
TimeBinnableType, TimeBinnableTypeAggregator, WithLen, WithTimestamps,
|
||||
FrameTypeInnerStatic, NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile, TimeBinnableType,
|
||||
TimeBinnableTypeAggregator, WithLen, WithTimestamps,
|
||||
};
|
||||
use err::Error;
|
||||
use netpod::log::*;
|
||||
@@ -17,16 +17,10 @@ pub struct StatsEvents {
|
||||
pub pulses: Vec<u64>,
|
||||
}
|
||||
|
||||
impl FrameTypeStaticSYC for StatsEvents {
|
||||
impl FrameTypeInnerStatic for StatsEvents {
|
||||
const FRAME_TYPE_ID: u32 = crate::STATS_EVENTS_FRAME_TYPE_ID;
|
||||
}
|
||||
|
||||
impl SitemtyFrameType for StatsEvents {
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl StatsEvents {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
|
||||
@@ -4,8 +4,8 @@ use crate::xbinnedscalarevents::XBinnedScalarEvents;
|
||||
use crate::xbinnedwaveevents::XBinnedWaveEvents;
|
||||
use crate::{
|
||||
Appendable, ByteEstimate, Clearable, EventAppendable, EventsDyn, EventsNodeProcessor, FilterFittingInside, Fits,
|
||||
FitsInside, FrameTypeStaticSYC, NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile,
|
||||
SitemtyFrameType, SubFrId, TimeBinnableDyn, TimeBinnableType, TimeBinnableTypeAggregator, WithLen, WithTimestamps,
|
||||
FitsInside, FrameTypeInnerStatic, NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile, SubFrId,
|
||||
TimeBinnableDyn, TimeBinnableType, TimeBinnableTypeAggregator, WithLen, WithTimestamps,
|
||||
};
|
||||
use err::Error;
|
||||
use netpod::log::*;
|
||||
@@ -40,22 +40,13 @@ impl<NTY> WaveEvents<NTY> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> FrameTypeStaticSYC for WaveEvents<NTY>
|
||||
impl<NTY> FrameTypeInnerStatic for WaveEvents<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = crate::WAVE_EVENTS_FRAME_TYPE_ID + NTY::SUB;
|
||||
}
|
||||
|
||||
impl<NTY> SitemtyFrameType for WaveEvents<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> WaveEvents<NTY> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
|
||||
@@ -2,8 +2,8 @@ use crate::binsdim0::MinMaxAvgDim0Bins;
|
||||
use crate::numops::NumOps;
|
||||
use crate::streams::{Collectable, Collector};
|
||||
use crate::{
|
||||
ts_offs_from_abs, Appendable, ByteEstimate, Clearable, FilterFittingInside, Fits, FitsInside, FrameTypeStaticSYC,
|
||||
NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile, SitemtyFrameType, SubFrId, TimeBinnableType,
|
||||
ts_offs_from_abs, Appendable, ByteEstimate, Clearable, FilterFittingInside, Fits, FitsInside, FrameTypeInnerStatic,
|
||||
NewEmpty, PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile, SubFrId, TimeBinnableType,
|
||||
TimeBinnableTypeAggregator, WithLen, WithTimestamps,
|
||||
};
|
||||
use err::Error;
|
||||
@@ -23,29 +23,20 @@ pub struct XBinnedScalarEvents<NTY> {
|
||||
pub avgs: Vec<f32>,
|
||||
}
|
||||
|
||||
impl<NTY> FrameTypeStaticSYC for XBinnedScalarEvents<NTY>
|
||||
impl<NTY> FrameTypeInnerStatic for XBinnedScalarEvents<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = crate::X_BINNED_SCALAR_EVENTS_FRAME_TYPE_ID + NTY::SUB;
|
||||
}
|
||||
|
||||
impl<NTY> SitemtyFrameType for XBinnedScalarEvents<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> XBinnedScalarEvents<NTY> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
tss: vec![],
|
||||
mins: vec![],
|
||||
maxs: vec![],
|
||||
avgs: vec![],
|
||||
tss: Vec::new(),
|
||||
mins: Vec::new(),
|
||||
maxs: Vec::new(),
|
||||
avgs: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@ use crate::binsdim1::MinMaxAvgDim1Bins;
|
||||
use crate::numops::NumOps;
|
||||
use crate::streams::{Collectable, Collector};
|
||||
use crate::{
|
||||
Appendable, ByteEstimate, Clearable, FilterFittingInside, Fits, FitsInside, FrameTypeStaticSYC, NewEmpty,
|
||||
PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile, SitemtyFrameType, SubFrId, TimeBinnableType,
|
||||
TimeBinnableTypeAggregator, WithLen, WithTimestamps,
|
||||
Appendable, ByteEstimate, Clearable, FilterFittingInside, Fits, FitsInside, FrameTypeInnerStatic, NewEmpty,
|
||||
PushableIndex, RangeOverlapInfo, ReadPbv, ReadableFromFile, SubFrId, TimeBinnableType, TimeBinnableTypeAggregator,
|
||||
WithLen, WithTimestamps,
|
||||
};
|
||||
use err::Error;
|
||||
use netpod::log::*;
|
||||
@@ -23,23 +23,13 @@ pub struct XBinnedWaveEvents<NTY> {
|
||||
pub avgs: Vec<Vec<f32>>,
|
||||
}
|
||||
|
||||
impl<NTY> FrameTypeStaticSYC for XBinnedWaveEvents<NTY>
|
||||
impl<NTY> FrameTypeInnerStatic for XBinnedWaveEvents<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
const FRAME_TYPE_ID: u32 = crate::X_BINNED_WAVE_EVENTS_FRAME_TYPE_ID + NTY::SUB;
|
||||
}
|
||||
|
||||
// TODO use a generic impl for this:
|
||||
impl<NTY> SitemtyFrameType for XBinnedWaveEvents<NTY>
|
||||
where
|
||||
NTY: SubFrId,
|
||||
{
|
||||
fn frame_type_id(&self) -> u32 {
|
||||
<Self as FrameTypeStaticSYC>::FRAME_TYPE_ID
|
||||
}
|
||||
}
|
||||
|
||||
impl<NTY> XBinnedWaveEvents<NTY> {
|
||||
pub fn empty() -> Self {
|
||||
Self {
|
||||
|
||||
Reference in New Issue
Block a user