use crate::{stdout, unwrap, Mat, SepBy};
use std::io::{self, Write};
mod impls;
mod macros;
pub(super) mod writer;
type Result<T = ()> = io::Result<T>;
pub trait WriteOneInto {
const SEP_ITEM: &'static str = " ";
const SEP_LINE: &'static str = "\n";
fn try_write_one_into<S: Write + ?Sized>(&self, s: &mut S) -> Result;
#[track_caller]
#[inline]
fn write_one_into<S: Write + ?Sized>(&self, s: &mut S) {
unwrap!(self.try_write_one_into(s))
}
}
impl<T: WriteOneInto + ?Sized> WriteOneInto for &T {
fn try_write_one_into<S: Write + ?Sized>(&self, s: &mut S) -> Result {
(*self).try_write_one_into(s)
}
}
pub trait WriteInto {
fn try_write_into<S: Write + ?Sized>(&self, s: &mut S) -> Result;
#[track_caller]
#[inline]
fn write_into<S: Write + ?Sized>(&self, s: &mut S) {
unwrap!(self.try_write_into(s))
}
fn try_write_into_string(&self) -> Result<String> {
let mut s = Vec::new();
self.try_write_into(&mut s)?;
String::from_utf8(s).map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))
}
#[track_caller]
#[inline]
fn write_into_string(&self) -> String {
unwrap!(self.try_write_into_string())
}
fn try_write(&self) -> Result {
self.try_write_into(&mut stdout())
}
#[track_caller]
#[inline]
fn write(&self) {
unwrap!(self.try_write())
}
}
impl<T: WriteOneInto> WriteInto for T {
fn try_write_into<S: Write + ?Sized>(&self, s: &mut S) -> Result<()> {
self.try_write_one_into(s)
}
}
impl<T: WriteOneInto> WriteInto for Vec<T> {
fn try_write_into<S: Write + ?Sized>(&self, s: &mut S) -> Result<()> {
self.as_slice().try_write_into(s)
}
}
impl<T: WriteOneInto, const N: usize> WriteInto for [T; N] {
fn try_write_into<S: Write + ?Sized>(&self, s: &mut S) -> Result<()> {
self.as_slice().try_write_into(s)
}
}
impl<T: WriteOneInto> WriteInto for [T] {
fn try_write_into<S: Write + ?Sized>(&self, s: &mut S) -> Result<()> {
WriteInto::try_write_into(&self.sep_by(T::SEP_ITEM), s)
}
}
impl<T: WriteOneInto> WriteInto for Mat<T> {
fn try_write_into<S: Write + ?Sized>(&self, s: &mut S) -> Result<()> {
self.iter()
.map(|row| row.iter().sep_by(T::SEP_ITEM))
.sep_by(T::SEP_LINE)
.try_write_into(s)
}
}
impl<T: WriteOneInto, const M: usize, const N: usize> WriteInto for [[T; N]; M] {
fn try_write_into<S: Write + ?Sized>(&self, s: &mut S) -> Result<()> {
self.iter()
.map(|row| row.iter().sep_by(T::SEP_ITEM))
.sep_by(T::SEP_LINE)
.try_write_into(s)
}
}