Struct jomini::TextWriter
source · pub struct TextWriter<W> { /* private fields */ }
Expand description
Write data in PDS format.
Instantiated via TextWriterBuilder
Implementations§
source§impl<W> TextWriter<W>where
W: Write,
impl<W> TextWriter<W>where
W: Write,
sourcepub fn into_inner(self) -> W
pub fn into_inner(self) -> W
Consumes this Writer, returning the underlying writer
sourcepub fn expecting_key(&self) -> bool
pub fn expecting_key(&self) -> bool
Returns true if the next write event would be a key
sourcepub fn write_object_start(&mut self) -> Result<(), Error>
pub fn write_object_start(&mut self) -> Result<(), Error>
Write out the start of an object
sourcepub fn write_array_start(&mut self) -> Result<(), Error>
pub fn write_array_start(&mut self) -> Result<(), Error>
Write out the start of an array
Examples found in repository?
622 623 624 625 626 627 628 629 630 631 632 633 634
fn write_array<R>(&mut self, array: ArrayReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
self.write_array_start()?;
for value in array.values() {
self.write_value(value)?;
}
self.write_end()?;
Ok(())
}
sourcepub fn write_end(&mut self) -> Result<(), Error>
pub fn write_end(&mut self) -> Result<(), Error>
Write the end of an array or object
Examples found in repository?
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
fn write_array<R>(&mut self, array: ArrayReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
self.write_array_start()?;
for value in array.values() {
self.write_value(value)?;
}
self.write_end()?;
Ok(())
}
fn write_object<R>(&mut self, object: ObjectReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
self.write_object_start()?;
self.write_object_core(object)?;
self.write_end()?;
Ok(())
}
sourcepub fn write_bool(&mut self, data: bool) -> Result<(), Error>
pub fn write_bool(&mut self, data: bool) -> Result<(), Error>
Write a boolean
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"hello")?;
writer.write_bool(true)?;
writer.write_unquoted(b"foo")?;
writer.write_bool(false)?;
assert_eq!(&out, b"hello=yes\nfoo=no");
sourcepub fn write_operator(&mut self, data: Operator) -> Result<(), Error>
pub fn write_operator(&mut self, data: Operator) -> Result<(), Error>
Write an non-equal operator
use jomini::{text::Operator, TextWriterBuilder};
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"a")?;
writer.write_operator(Operator::LessThan)?;
writer.write_unquoted(b"b")?;
assert_eq!(&out, b"a < b");
Examples found in repository?
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
fn write_object_core<R>(&mut self, reader: ObjectReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
for (key, op, value) in reader.fields() {
match key.token() {
TextToken::Parameter(x) => {
self.write_preamble()?;
write!(self.writer, "[[")?;
self.writer.write_all(x.as_bytes())?;
self.writer.write_all(b"]\n")?;
if let Ok(obj) = value.read_object() {
self.write_object_core(obj)?;
self.writer.write_all(b"\n")?;
self.write_indent()?;
} else {
self.write_value(value)?;
}
self.writer.write_all(b"]")?;
}
TextToken::UndefinedParameter(x) => {
self.write_preamble()?;
write!(self.writer, "[[!")?;
self.writer.write_all(x.as_bytes())?;
self.writer.write_all(b"]\n")?;
if let Ok(obj) = value.read_object() {
self.write_object_core(obj)?;
self.writer.write_all(b"\n")?;
self.write_indent()?;
} else {
self.write_value(value)?;
}
self.writer.write_all(b"]")?;
}
TextToken::Quoted(x) => {
self.write_escaped_quotes(x.as_bytes())?;
if let Some(op) = op {
self.write_operator(op)?;
}
self.write_value(value)?;
}
_ => {
self.write_unquoted(key.read_scalar().as_bytes())?;
if let Some(op) = op {
self.write_operator(op)?;
}
self.write_value(value)?;
}
}
}
Ok(())
}
sourcepub fn write_unquoted(&mut self, data: &[u8]) -> Result<(), Error>
pub fn write_unquoted(&mut self, data: &[u8]) -> Result<(), Error>
Write bytes directly to the writer.
The contents of the bytes are not checked, so it is up to the caller to ensure that the data is a valid unquoted field (no spaces or control characters).
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"a")?;
writer.write_unquoted(b"b")?;
assert_eq!(&out, b"a=b");
Examples found in repository?
517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
fn write_object_core<R>(&mut self, reader: ObjectReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
for (key, op, value) in reader.fields() {
match key.token() {
TextToken::Parameter(x) => {
self.write_preamble()?;
write!(self.writer, "[[")?;
self.writer.write_all(x.as_bytes())?;
self.writer.write_all(b"]\n")?;
if let Ok(obj) = value.read_object() {
self.write_object_core(obj)?;
self.writer.write_all(b"\n")?;
self.write_indent()?;
} else {
self.write_value(value)?;
}
self.writer.write_all(b"]")?;
}
TextToken::UndefinedParameter(x) => {
self.write_preamble()?;
write!(self.writer, "[[!")?;
self.writer.write_all(x.as_bytes())?;
self.writer.write_all(b"]\n")?;
if let Ok(obj) = value.read_object() {
self.write_object_core(obj)?;
self.writer.write_all(b"\n")?;
self.write_indent()?;
} else {
self.write_value(value)?;
}
self.writer.write_all(b"]")?;
}
TextToken::Quoted(x) => {
self.write_escaped_quotes(x.as_bytes())?;
if let Some(op) = op {
self.write_operator(op)?;
}
self.write_value(value)?;
}
_ => {
self.write_unquoted(key.read_scalar().as_bytes())?;
if let Some(op) = op {
self.write_operator(op)?;
}
self.write_value(value)?;
}
}
}
Ok(())
}
// For when the data is already escaped
fn write_escaped_quotes(&mut self, x: &[u8]) -> Result<(), Error> {
self.write_preamble()?;
self.writer.write_all(b"\"")?;
self.writer.write_all(x)?;
self.writer.write_all(b"\"")?;
self.write_epilogue()?;
Ok(())
}
fn write_value<R>(&mut self, value: ValueReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
match value.token() {
TextToken::Array { .. } => self.write_array(value.read_array().unwrap())?,
TextToken::Object { .. } => self.write_object(value.read_object().unwrap())?,
TextToken::MixedContainer => self.start_mixed_mode(),
TextToken::Unquoted(x) => {
self.write_unquoted(x.as_bytes())?;
}
TextToken::Quoted(x) => {
self.write_escaped_quotes(x.as_bytes())?;
}
TextToken::Parameter(_) => unreachable!(),
TextToken::UndefinedParameter(_) => unreachable!(),
TextToken::Operator(op) => {
if self.mixed_mode == MixedMode::Disabled {
self.writer.write_all(&b" "[..])?;
} else {
self.mixed_mode = MixedMode::Keyed;
}
self.writer.write_all(op.symbol().as_bytes())?;
}
TextToken::End(_) => unreachable!(),
TextToken::Header(x) => {
let arr = value.read_array().unwrap();
let mut values = arr.values();
self.write_header(x.as_bytes())?;
values.next().unwrap();
let elem = values.next().unwrap();
self.write_value(elem)?;
}
}
Ok(())
}
sourcepub fn write_quoted(&mut self, data: &[u8]) -> Result<(), Error>
pub fn write_quoted(&mut self, data: &[u8]) -> Result<(), Error>
Write a field to be encapsulated in quotes.
Unlike the unquoted variant, this method will inspect the data to ensure everything is properly escaped, like quotes and escape characters. And will trim trailing newlines. The textual data to write out is assumed to already be in the correct encoding (windows-1252 or UTF-8)
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_quoted(b"name")?;
writer.write_quoted(br#"captain "joe" rogers"#)?;
assert_eq!(&out, b"\"name\"=\"captain \\\"joe\\\" rogers\"");
sourcepub fn write_i32(&mut self, data: i32) -> Result<(), Error>
pub fn write_i32(&mut self, data: i32) -> Result<(), Error>
Write a signed 32bit integer.
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"stability")?;
writer.write_i32(-3);
assert_eq!(&out, b"stability=-3");
sourcepub fn write_u32(&mut self, data: u32) -> Result<(), Error>
pub fn write_u32(&mut self, data: u32) -> Result<(), Error>
Write an unsigned 32bit integer.
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"stability")?;
writer.write_u32(3);
assert_eq!(&out, b"stability=3");
sourcepub fn write_u64(&mut self, data: u64) -> Result<(), Error>
pub fn write_u64(&mut self, data: u64) -> Result<(), Error>
Write an unsigned 64bit integer.
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"seed")?;
writer.write_u64(1000000000000);
assert_eq!(&out, b"seed=1000000000000");
sourcepub fn write_f32(&mut self, data: f32) -> Result<(), Error>
pub fn write_f32(&mut self, data: f32) -> Result<(), Error>
Write a 32 bit floating point at full precision
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"morale")?;
writer.write_f32(4.566);
assert_eq!(&out, b"morale=4.566");
sourcepub fn write_f32_precision(
&mut self,
data: f32,
precision: usize
) -> Result<(), Error>
pub fn write_f32_precision(
&mut self,
data: f32,
precision: usize
) -> Result<(), Error>
Write a 32 bit floating point at a given precision
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"morale")?;
writer.write_f32_precision(4.0, 3);
assert_eq!(&out, b"morale=4.000");
sourcepub fn write_f64(&mut self, data: f64) -> Result<(), Error>
pub fn write_f64(&mut self, data: f64) -> Result<(), Error>
Write a 64 bit floating point at full precision
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"strength")?;
writer.write_f64(6790.35609);
assert_eq!(&out, b"strength=6790.35609");
sourcepub fn write_f64_precision(
&mut self,
data: f64,
precision: usize
) -> Result<(), Error>
pub fn write_f64_precision(
&mut self,
data: f64,
precision: usize
) -> Result<(), Error>
Write a 64 bit floating point at a given precision
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"morale")?;
writer.write_f64_precision(4.0, 3);
assert_eq!(&out, b"morale=4.000");
sourcepub fn write_header(&mut self, header: &[u8]) -> Result<(), Error>
pub fn write_header(&mut self, header: &[u8]) -> Result<(), Error>
Write a header.
It is undefined if the next commands do not write out the start of an array or object
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"color")?;
writer.write_header(b"rgb")?;
writer.write_array_start()?;
writer.write_i32(100)?;
writer.write_i32(200)?;
writer.write_i32(50)?;
writer.write_end()?;
assert_eq!(&out, b"color=rgb {\n 100 200 50\n}");
Examples found in repository?
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
fn write_value<R>(&mut self, value: ValueReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
match value.token() {
TextToken::Array { .. } => self.write_array(value.read_array().unwrap())?,
TextToken::Object { .. } => self.write_object(value.read_object().unwrap())?,
TextToken::MixedContainer => self.start_mixed_mode(),
TextToken::Unquoted(x) => {
self.write_unquoted(x.as_bytes())?;
}
TextToken::Quoted(x) => {
self.write_escaped_quotes(x.as_bytes())?;
}
TextToken::Parameter(_) => unreachable!(),
TextToken::UndefinedParameter(_) => unreachable!(),
TextToken::Operator(op) => {
if self.mixed_mode == MixedMode::Disabled {
self.writer.write_all(&b" "[..])?;
} else {
self.mixed_mode = MixedMode::Keyed;
}
self.writer.write_all(op.symbol().as_bytes())?;
}
TextToken::End(_) => unreachable!(),
TextToken::Header(x) => {
let arr = value.read_array().unwrap();
let mut values = arr.values();
self.write_header(x.as_bytes())?;
values.next().unwrap();
let elem = values.next().unwrap();
self.write_value(elem)?;
}
}
Ok(())
}
sourcepub fn write_date(&mut self, data: PdsDateFormatter) -> Result<(), Error>
pub fn write_date(&mut self, data: PdsDateFormatter) -> Result<(), Error>
Write a date formatted in the game style
use jomini::{common::{Date, PdsDate}, TextWriterBuilder};
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
let date = Date::from_ymd(1444, 11, 11);
writer.write_unquoted(b"start")?;
writer.write_date(date.game_fmt())?;
assert_eq!(&out, b"start=1444.11.11");
sourcepub fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>
pub fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>
Write formatted data
Typically not invoked directly but instead through the write!
macro
use jomini::TextWriterBuilder;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_unquoted(b"start")?;
write!(writer, "unknown_{}", 5)?;
assert_eq!(&out, b"start=unknown_5");
sourcepub fn start_mixed_mode(&mut self)
pub fn start_mixed_mode(&mut self)
Enter mixed mode for writing a container that is a list and an object
Examples found in repository?
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
fn write_value<R>(&mut self, value: ValueReader<R>) -> Result<(), Error>
where
R: Encoding + Clone,
{
match value.token() {
TextToken::Array { .. } => self.write_array(value.read_array().unwrap())?,
TextToken::Object { .. } => self.write_object(value.read_object().unwrap())?,
TextToken::MixedContainer => self.start_mixed_mode(),
TextToken::Unquoted(x) => {
self.write_unquoted(x.as_bytes())?;
}
TextToken::Quoted(x) => {
self.write_escaped_quotes(x.as_bytes())?;
}
TextToken::Parameter(_) => unreachable!(),
TextToken::UndefinedParameter(_) => unreachable!(),
TextToken::Operator(op) => {
if self.mixed_mode == MixedMode::Disabled {
self.writer.write_all(&b" "[..])?;
} else {
self.mixed_mode = MixedMode::Keyed;
}
self.writer.write_all(op.symbol().as_bytes())?;
}
TextToken::End(_) => unreachable!(),
TextToken::Header(x) => {
let arr = value.read_array().unwrap();
let mut values = arr.values();
self.write_header(x.as_bytes())?;
values.next().unwrap();
let elem = values.next().unwrap();
self.write_value(elem)?;
}
}
Ok(())
}
sourcepub fn write_tape(&mut self, tape: &TextTape<'_>) -> Result<(), Error>
pub fn write_tape(&mut self, tape: &TextTape<'_>) -> Result<(), Error>
Writes a text tape
Formatting is not preserved.
use jomini::{TextTape, TextWriterBuilder};
let tape = TextTape::from_slice(b"hello=world")?;
let mut out: Vec<u8> = Vec::new();
let mut writer = TextWriterBuilder::new().from_writer(&mut out);
writer.write_tape(&tape)?;
assert_eq!(&out, b"hello=world");