use std::io::{Write, Result, Error, ErrorKind};
use byteorder::{ByteOrder, WriteBytesExt};
pub trait Utf16WriteExt: WriteBytesExt {
fn write_shorts<T: ByteOrder>(&mut self, buf: &[u16]) -> Result<usize> {
let mut len = 0;
for &short in buf {
match self.write_u16::<T>(short) {
Ok(()) => (),
Err(_) if len > 0 => return Ok(len),
Err(e) => return Err(e),
}
len += 1;
}
Ok(len)
}
fn write_all_shorts<T: ByteOrder>(&mut self, mut buf: &[u16]) -> Result<()> {
while !buf.is_empty() {
match self.write_shorts::<T>(buf) {
Ok(0) => return Err(Error::new(ErrorKind::WriteZero,
"failed to write whole buffer")),
Ok(n) => buf = &buf[n..],
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(e),
}
}
Ok(())
}
fn write_bom<T: ByteOrder>(&mut self) -> Result<()> {
self.write_u16::<T>(0xfeff)
}
fn write_utf16_string<'a, T: ByteOrder>(&mut self, s: &'a str) -> Result<Utf16Written<'a>> {
let mut encoder = s.encode_utf16();
if let Some(short) = encoder.next() {
match self.write_u16::<T>(short) {
Ok(()) => (),
Err(e) => return Err(e),
}
}
while let Some(short) = encoder.next() {
match self.write_u16::<T>(short) {
Ok(()) => (),
Err(_) => return Ok(Utf16Written::Missing(encoder)),
}
}
Ok(Utf16Written::FullyComplete)
}
}
impl<T: Write> Utf16WriteExt for T {}
use std::str::EncodeUtf16;
pub enum Utf16Written<'a> {
FullyComplete,
Missing(EncodeUtf16<'a>)
}