@@ -4,6 +4,8 @@ use std::{
44 sync:: OnceLock ,
55} ;
66
7+ use ouroboros:: self_referencing;
8+
79use crate :: {
810 helpers:: {
911 get_generated_source_info, stream_chunks_of_raw_source, OnChunk , OnName ,
@@ -362,61 +364,85 @@ impl StreamChunks for RawStringSource {
362364/// assert_eq!(s.map(&MapOptions::default()), None);
363365/// assert_eq!(s.size(), 16);
364366/// ```
365- #[ derive ( Clone , PartialEq , Eq ) ]
367+ #[ self_referencing ]
366368pub struct RawBufferSource {
367369 value : Vec < u8 > ,
368- value_as_string : OnceLock < String > ,
370+ #[ borrows( value) ]
371+ #[ not_covariant]
372+ value_as_string : OnceLock < Cow < ' this , str > > ,
373+ }
374+
375+ impl RawBufferSource {
376+ fn get_or_init_value_as_string ( & self ) -> & str {
377+ self . with ( |fields| {
378+ fields
379+ . value_as_string
380+ . get_or_init ( || String :: from_utf8_lossy ( fields. value ) )
381+ } )
382+ }
369383}
370384
385+ impl Clone for RawBufferSource {
386+ fn clone ( & self ) -> Self {
387+ RawBufferSourceBuilder {
388+ value : self . borrow_value ( ) . clone ( ) ,
389+ value_as_string_builder : |_: & Vec < u8 > | Default :: default ( ) ,
390+ }
391+ . build ( )
392+ }
393+ }
394+
395+ impl PartialEq for RawBufferSource {
396+ fn eq ( & self , other : & Self ) -> bool {
397+ self . borrow_value ( ) == other. borrow_value ( )
398+ }
399+ }
400+
401+ impl Eq for RawBufferSource { }
402+
371403impl From < Vec < u8 > > for RawBufferSource {
372404 fn from ( value : Vec < u8 > ) -> Self {
373- Self {
405+ RawBufferSourceBuilder {
374406 value,
375- value_as_string : Default :: default ( ) ,
407+ value_as_string_builder : |_ : & Vec < u8 > | Default :: default ( ) ,
376408 }
409+ . build ( )
377410 }
378411}
379412
380413impl From < & [ u8 ] > for RawBufferSource {
381414 fn from ( value : & [ u8 ] ) -> Self {
382- Self {
415+ RawBufferSourceBuilder {
383416 value : value. to_vec ( ) ,
384- value_as_string : Default :: default ( ) ,
417+ value_as_string_builder : |_ : & Vec < u8 > | Default :: default ( ) ,
385418 }
419+ . build ( )
386420 }
387421}
388422
389423impl Source for RawBufferSource {
390424 fn source ( & self ) -> Cow < str > {
391- Cow :: Borrowed (
392- self
393- . value_as_string
394- . get_or_init ( || String :: from_utf8_lossy ( & self . value ) . to_string ( ) ) ,
395- )
425+ Cow :: Borrowed ( self . get_or_init_value_as_string ( ) )
396426 }
397427
398428 fn rope ( & self ) -> Rope < ' _ > {
399- Rope :: from (
400- self
401- . value_as_string
402- . get_or_init ( || String :: from_utf8_lossy ( & self . value ) . to_string ( ) ) ,
403- )
429+ Rope :: from ( self . get_or_init_value_as_string ( ) )
404430 }
405431
406432 fn buffer ( & self ) -> Cow < [ u8 ] > {
407- Cow :: Borrowed ( & self . value )
433+ Cow :: Borrowed ( self . borrow_value ( ) )
408434 }
409435
410436 fn size ( & self ) -> usize {
411- self . value . len ( )
437+ self . borrow_value ( ) . len ( )
412438 }
413439
414440 fn map ( & self , _: & MapOptions ) -> Option < SourceMap > {
415441 None
416442 }
417443
418444 fn to_writer ( & self , writer : & mut dyn std:: io:: Write ) -> std:: io:: Result < ( ) > {
419- writer. write_all ( & self . value )
445+ writer. write_all ( self . borrow_value ( ) )
420446 }
421447}
422448
@@ -430,7 +456,7 @@ impl std::fmt::Debug for RawBufferSource {
430456 write ! (
431457 f,
432458 "{indent_str}RawBufferSource::from({:?}).boxed()" ,
433- self . value
459+ self . borrow_value ( )
434460 )
435461 }
436462}
@@ -454,9 +480,7 @@ impl StreamChunks for RawBufferSource {
454480 get_generated_source_info ( & * self . source ( ) )
455481 } else {
456482 stream_chunks_of_raw_source (
457- & * * self
458- . value_as_string
459- . get_or_init ( || String :: from_utf8_lossy ( & self . value ) . to_string ( ) ) ,
483+ self . get_or_init_value_as_string ( ) ,
460484 options,
461485 on_chunk,
462486 on_source,
0 commit comments