io_streams/buffered/
buf_reader_line_writer.rs1use super::buf_duplexer::BufDuplexerBackend;
5use super::{BufReaderLineWriterShim, IntoInnerError};
6use duplex::HalfDuplex;
7#[cfg(feature = "layered-io")]
8use layered_io::{Bufferable, HalfDuplexLayered};
9use std::fmt;
10#[cfg(read_initializer)]
11use std::io::Initializer;
12use std::io::{self, BufRead, IoSlice, IoSliceMut, Read, Write};
13#[cfg(not(windows))]
14use {
15 io_extras::os::rustix::{AsRawFd, RawFd},
16 io_lifetimes::{AsFd, BorrowedFd},
17};
18#[cfg(windows)]
19use {
20 io_extras::os::windows::{
21 AsHandleOrSocket, AsRawHandleOrSocket, BorrowedHandleOrSocket, RawHandleOrSocket,
22 },
23 io_lifetimes::{AsHandle, AsSocket, BorrowedHandle, BorrowedSocket},
24 std::os::windows::io::{AsRawHandle, AsRawSocket, RawHandle, RawSocket},
25};
26
27pub struct BufReaderLineWriter<Inner: HalfDuplex> {
97 inner: BufReaderLineWriterBackend<Inner>,
98}
99
100struct BufReaderLineWriterBackend<Inner: HalfDuplex> {
105 inner: BufDuplexerBackend<Inner>,
106}
107
108impl<Inner: HalfDuplex> BufReaderLineWriter<Inner> {
109 #[inline]
124 pub fn new(inner: Inner) -> Self {
125 Self {
126 inner: BufReaderLineWriterBackend::new(inner),
127 }
128 }
129
130 #[inline]
146 pub fn with_capacities(reader_capacity: usize, writer_capacity: usize, inner: Inner) -> Self {
147 Self {
148 inner: BufReaderLineWriterBackend::with_capacities(
149 reader_capacity,
150 writer_capacity,
151 inner,
152 ),
153 }
154 }
155
156 #[inline]
173 pub fn get_ref(&self) -> &Inner {
174 self.inner.get_ref()
175 }
176
177 #[inline]
198 pub fn get_mut(&mut self) -> &mut Inner {
199 self.inner.get_mut()
200 }
201
202 #[inline]
227 pub fn into_inner(self) -> Result<Inner, IntoInnerError<Self>> {
228 self.inner
229 .into_inner()
230 .map_err(|err| err.new_wrapped(|inner| Self { inner }))
231 }
232}
233
234impl<Inner: HalfDuplex> BufReaderLineWriterBackend<Inner> {
235 pub fn new(inner: Inner) -> Self {
236 Self::with_capacities(1024, 1024, inner)
238 }
239
240 pub fn with_capacities(reader_capacity: usize, writer_capacity: usize, inner: Inner) -> Self {
241 Self {
242 inner: BufDuplexerBackend::with_capacities(reader_capacity, writer_capacity, inner),
243 }
244 }
245
246 #[inline]
247 pub fn get_ref(&self) -> &Inner {
248 self.inner.get_ref()
249 }
250
251 #[inline]
252 pub fn get_mut(&mut self) -> &mut Inner {
253 self.inner.get_mut()
254 }
255
256 pub fn into_inner(self) -> Result<Inner, IntoInnerError<Self>> {
257 self.inner
258 .into_inner()
259 .map_err(|err| err.new_wrapped(|inner| Self { inner }))
260 }
261}
262
263impl<Inner: HalfDuplex> Write for BufReaderLineWriter<Inner> {
264 #[inline]
265 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
266 self.inner.write(buf)
267 }
268
269 #[inline]
270 fn flush(&mut self) -> io::Result<()> {
271 self.inner.flush()
272 }
273
274 #[inline]
275 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
276 self.inner.write_vectored(bufs)
277 }
278
279 #[cfg(can_vector)]
280 #[inline]
281 fn is_write_vectored(&self) -> bool {
282 self.inner.is_write_vectored()
283 }
284
285 #[inline]
286 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
287 self.inner.write_all(buf)
288 }
289
290 #[cfg(write_all_vectored)]
291 #[inline]
292 fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
293 self.inner.write_all_vectored(bufs)
294 }
295
296 #[inline]
297 fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
298 self.inner.write_fmt(fmt)
299 }
300}
301
302impl<Inner: HalfDuplex> Write for BufReaderLineWriterBackend<Inner> {
303 #[inline]
304 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
305 BufReaderLineWriterShim::new(&mut self.inner).write(buf)
306 }
307
308 #[inline]
309 fn flush(&mut self) -> io::Result<()> {
310 self.inner.flush()
311 }
312
313 #[inline]
314 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
315 BufReaderLineWriterShim::new(&mut self.inner).write_vectored(bufs)
316 }
317
318 #[cfg(can_vector)]
319 #[inline]
320 fn is_write_vectored(&self) -> bool {
321 self.inner.is_write_vectored()
322 }
323
324 #[inline]
325 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
326 BufReaderLineWriterShim::new(&mut self.inner).write_all(buf)
327 }
328
329 #[cfg(write_all_vectored)]
330 #[inline]
331 fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> {
332 BufReaderLineWriterShim::new(&mut self.inner).write_all_vectored(bufs)
333 }
334
335 #[inline]
336 fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
337 BufReaderLineWriterShim::new(&mut self.inner).write_fmt(fmt)
338 }
339}
340
341impl<Inner: HalfDuplex> Read for BufReaderLineWriter<Inner> {
342 #[inline]
343 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
344 self.inner.flush()?;
346
347 self.inner.read(buf)
348 }
349
350 #[inline]
351 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
352 self.inner.flush()?;
354
355 self.inner.read_vectored(bufs)
356 }
357
358 #[cfg(can_vector)]
359 #[inline]
360 fn is_read_vectored(&self) -> bool {
361 self.inner.is_read_vectored()
362 }
363
364 #[cfg(read_initializer)]
365 #[inline]
366 unsafe fn initializer(&self) -> Initializer {
367 self.inner.initializer()
368 }
369}
370
371impl<Inner: HalfDuplex> Read for BufReaderLineWriterBackend<Inner> {
372 #[inline]
373 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
374 self.inner.read(buf)
375 }
376
377 #[inline]
378 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
379 self.inner.read_vectored(bufs)
380 }
381
382 #[cfg(can_vector)]
383 #[inline]
384 fn is_read_vectored(&self) -> bool {
385 self.inner.is_read_vectored()
386 }
387
388 #[cfg(read_initializer)]
390 #[inline]
391 unsafe fn initializer(&self) -> Initializer {
392 self.inner.initializer()
393 }
394}
395
396impl<Inner: HalfDuplex> BufRead for BufReaderLineWriter<Inner> {
397 #[inline]
398 fn fill_buf(&mut self) -> io::Result<&[u8]> {
399 self.inner.fill_buf()
400 }
401
402 #[inline]
403 fn consume(&mut self, amt: usize) {
404 self.inner.consume(amt)
405 }
406
407 #[inline]
408 fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<usize> {
409 self.flush()?;
411
412 self.inner.read_until(byte, buf)
413 }
414
415 #[inline]
416 fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
417 self.flush()?;
419
420 let t = self.inner.read_line(buf)?;
421
422 Ok(t)
423 }
424}
425
426impl<Inner: HalfDuplex> BufRead for BufReaderLineWriterBackend<Inner> {
427 #[inline]
428 fn fill_buf(&mut self) -> io::Result<&[u8]> {
429 self.inner.fill_buf()
430 }
431
432 #[inline]
433 fn consume(&mut self, amt: usize) {
434 self.inner.consume(amt)
435 }
436}
437
438impl<Inner: HalfDuplex> fmt::Debug for BufReaderLineWriter<Inner>
439where
440 Inner: fmt::Debug,
441{
442 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
443 self.inner.fmt(fmt)
444 }
445}
446
447impl<Inner: HalfDuplex> fmt::Debug for BufReaderLineWriterBackend<Inner>
448where
449 Inner: fmt::Debug,
450{
451 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
452 fmt.debug_struct("BufReaderLineWriter")
453 .field("inner", &self.get_ref())
454 .field(
455 "reader_buffer",
456 &format_args!(
457 "{}/{}",
458 self.inner.reader_buffer().len(),
459 self.inner.reader_capacity()
460 ),
461 )
462 .field(
463 "writer_buffer",
464 &format_args!(
465 "{}/{}",
466 self.inner.writer_buffer().len(),
467 self.inner.writer_capacity()
468 ),
469 )
470 .finish()
471 }
472}
473
474#[cfg(not(windows))]
475impl<Inner: HalfDuplex + AsRawFd> AsRawFd for BufReaderLineWriter<Inner> {
476 #[inline]
477 fn as_raw_fd(&self) -> RawFd {
478 self.inner.as_raw_fd()
479 }
480}
481
482#[cfg(windows)]
483impl<Inner: HalfDuplex + AsRawHandle> AsRawHandle for BufReaderLineWriter<Inner> {
484 #[inline]
485 fn as_raw_handle(&self) -> RawHandle {
486 self.inner.as_raw_handle()
487 }
488}
489
490#[cfg(windows)]
491impl<Inner: HalfDuplex + AsRawSocket> AsRawSocket for BufReaderLineWriter<Inner> {
492 #[inline]
493 fn as_raw_socket(&self) -> RawSocket {
494 self.inner.as_raw_socket()
495 }
496}
497
498#[cfg(windows)]
499impl<Inner: HalfDuplex + AsRawHandleOrSocket> AsRawHandleOrSocket for BufReaderLineWriter<Inner> {
500 #[inline]
501 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
502 self.inner.as_raw_handle_or_socket()
503 }
504}
505
506#[cfg(not(windows))]
507impl<Inner: HalfDuplex + AsRawFd> AsRawFd for BufReaderLineWriterBackend<Inner> {
508 #[inline]
509 fn as_raw_fd(&self) -> RawFd {
510 self.inner.as_raw_fd()
511 }
512}
513
514#[cfg(windows)]
515impl<Inner: HalfDuplex + AsRawHandle> AsRawHandle for BufReaderLineWriterBackend<Inner> {
516 #[inline]
517 fn as_raw_handle(&self) -> RawHandle {
518 self.inner.as_raw_handle()
519 }
520}
521
522#[cfg(windows)]
523impl<Inner: HalfDuplex + AsRawSocket> AsRawSocket for BufReaderLineWriterBackend<Inner> {
524 #[inline]
525 fn as_raw_socket(&self) -> RawSocket {
526 self.inner.as_raw_socket()
527 }
528}
529
530#[cfg(windows)]
531impl<Inner: HalfDuplex + AsRawHandleOrSocket> AsRawHandleOrSocket
532 for BufReaderLineWriterBackend<Inner>
533{
534 #[inline]
535 fn as_raw_handle_or_socket(&self) -> RawHandleOrSocket {
536 self.inner.as_raw_handle_or_socket()
537 }
538}
539
540#[cfg(not(windows))]
541impl<Inner: HalfDuplex + AsFd> AsFd for BufReaderLineWriter<Inner> {
542 #[inline]
543 fn as_fd(&self) -> BorrowedFd<'_> {
544 self.inner.as_fd()
545 }
546}
547
548#[cfg(windows)]
549impl<Inner: HalfDuplex + AsHandle> AsHandle for BufReaderLineWriter<Inner> {
550 #[inline]
551 fn as_handle(&self) -> BorrowedHandle<'_> {
552 self.inner.as_handle()
553 }
554}
555
556#[cfg(windows)]
557impl<Inner: HalfDuplex + AsSocket> AsSocket for BufReaderLineWriter<Inner> {
558 #[inline]
559 fn as_socket(&self) -> BorrowedSocket<'_> {
560 self.inner.as_socket()
561 }
562}
563
564#[cfg(windows)]
565impl<Inner: HalfDuplex + AsHandleOrSocket> AsHandleOrSocket for BufReaderLineWriter<Inner> {
566 #[inline]
567 fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
568 self.inner.as_handle_or_socket()
569 }
570}
571
572#[cfg(not(windows))]
573impl<Inner: HalfDuplex + AsFd> AsFd for BufReaderLineWriterBackend<Inner> {
574 #[inline]
575 fn as_fd(&self) -> BorrowedFd<'_> {
576 self.inner.as_fd()
577 }
578}
579
580#[cfg(windows)]
581impl<Inner: HalfDuplex + AsHandle> AsHandle for BufReaderLineWriterBackend<Inner> {
582 #[inline]
583 fn as_handle(&self) -> BorrowedHandle<'_> {
584 self.inner.as_handle()
585 }
586}
587
588#[cfg(windows)]
589impl<Inner: HalfDuplex + AsSocket> AsSocket for BufReaderLineWriterBackend<Inner> {
590 #[inline]
591 fn as_socket(&self) -> BorrowedSocket<'_> {
592 self.inner.as_socket()
593 }
594}
595
596#[cfg(windows)]
597impl<Inner: HalfDuplex + AsHandleOrSocket> AsHandleOrSocket for BufReaderLineWriterBackend<Inner> {
598 #[inline]
599 fn as_handle_or_socket(&self) -> BorrowedHandleOrSocket<'_> {
600 self.inner.as_handle_or_socket()
601 }
602}
603
604#[cfg(feature = "terminal-io")]
605impl<Inner: HalfDuplex + terminal_io::Terminal> terminal_io::Terminal
606 for BufReaderLineWriter<Inner>
607{
608}
609
610#[cfg(feature = "terminal-io")]
611impl<Inner: HalfDuplex + terminal_io::Terminal> terminal_io::Terminal
612 for BufReaderLineWriterBackend<Inner>
613{
614}
615
616#[cfg(feature = "terminal-io")]
617impl<Inner: HalfDuplex + terminal_io::WriteTerminal> terminal_io::WriteTerminal
618 for BufReaderLineWriter<Inner>
619{
620 #[inline]
621 fn color_support(&self) -> terminal_io::TerminalColorSupport {
622 self.inner.color_support()
623 }
624
625 #[inline]
626 fn color_preference(&self) -> bool {
627 self.inner.color_preference()
628 }
629
630 #[inline]
631 fn is_output_terminal(&self) -> bool {
632 self.inner.is_output_terminal()
633 }
634}
635
636#[cfg(feature = "terminal-io")]
637impl<Inner: HalfDuplex + terminal_io::WriteTerminal> terminal_io::WriteTerminal
638 for BufReaderLineWriterBackend<Inner>
639{
640 #[inline]
641 fn color_support(&self) -> terminal_io::TerminalColorSupport {
642 self.inner.color_support()
643 }
644
645 #[inline]
646 fn color_preference(&self) -> bool {
647 self.inner.color_preference()
648 }
649
650 #[inline]
651 fn is_output_terminal(&self) -> bool {
652 self.inner.is_output_terminal()
653 }
654}
655
656#[cfg(feature = "layered-io")]
657impl<Inner: HalfDuplexLayered> Bufferable for BufReaderLineWriter<Inner> {
658 #[inline]
659 fn abandon(&mut self) {
660 self.inner.abandon()
661 }
662
663 #[inline]
664 fn suggested_buffer_size(&self) -> usize {
665 self.inner.suggested_buffer_size()
666 }
667}
668
669#[cfg(feature = "layered-io")]
670impl<Inner: HalfDuplexLayered> Bufferable for BufReaderLineWriterBackend<Inner> {
671 #[inline]
672 fn abandon(&mut self) {
673 self.inner.abandon()
674 }
675
676 #[inline]
677 fn suggested_buffer_size(&self) -> usize {
678 self.inner.suggested_buffer_size()
679 }
680}