mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	rust: str: add Formatter type
				
					
				
			Add the `Formatter` type, which leverages `RawFormatter`, but fails if callers attempt to write more than will fit in the buffer. In order to so, implement the `RawFormatter::from_buffer()` constructor as well. Co-developed-by: Adam Bratschi-Kaye <ark.email@gmail.com> Signed-off-by: Adam Bratschi-Kaye <ark.email@gmail.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@gmail.com> Reviewed-by: Gary Guo <gary@garyguo.net> [Reworded, adapted for upstream and applied latest changes] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
		
							parent
							
								
									b18cb00e5a
								
							
						
					
					
						commit
						fffed679ee
					
				
					 1 changed files with 57 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -406,6 +406,23 @@ pub(crate) unsafe fn from_ptrs(pos: *mut u8, end: *mut u8) -> Self {
 | 
			
		|||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Creates a new instance of [`RawFormatter`] with the given buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Safety
 | 
			
		||||
    ///
 | 
			
		||||
    /// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
 | 
			
		||||
    /// for the lifetime of the returned [`RawFormatter`].
 | 
			
		||||
    pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
 | 
			
		||||
        let pos = buf as usize;
 | 
			
		||||
        // INVARIANT: We ensure that `end` is never less then `buf`, and the safety requirements
 | 
			
		||||
        // guarantees that the memory region is valid for writes.
 | 
			
		||||
        Self {
 | 
			
		||||
            pos,
 | 
			
		||||
            beg: pos,
 | 
			
		||||
            end: pos.saturating_add(len),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns the current insert position.
 | 
			
		||||
    ///
 | 
			
		||||
    /// N.B. It may point to invalid memory.
 | 
			
		||||
| 
						 | 
				
			
			@ -439,3 +456,43 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
 | 
			
		|||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Allows formatting of [`fmt::Arguments`] into a raw buffer.
 | 
			
		||||
///
 | 
			
		||||
/// Fails if callers attempt to write more than will fit in the buffer.
 | 
			
		||||
pub(crate) struct Formatter(RawFormatter);
 | 
			
		||||
 | 
			
		||||
impl Formatter {
 | 
			
		||||
    /// Creates a new instance of [`Formatter`] with the given buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// # Safety
 | 
			
		||||
    ///
 | 
			
		||||
    /// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
 | 
			
		||||
    /// for the lifetime of the returned [`Formatter`].
 | 
			
		||||
    #[allow(dead_code)]
 | 
			
		||||
    pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
 | 
			
		||||
        // SAFETY: The safety requirements of this function satisfy those of the callee.
 | 
			
		||||
        Self(unsafe { RawFormatter::from_buffer(buf, len) })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Deref for Formatter {
 | 
			
		||||
    type Target = RawFormatter;
 | 
			
		||||
 | 
			
		||||
    fn deref(&self) -> &Self::Target {
 | 
			
		||||
        &self.0
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl fmt::Write for Formatter {
 | 
			
		||||
    fn write_str(&mut self, s: &str) -> fmt::Result {
 | 
			
		||||
        self.0.write_str(s)?;
 | 
			
		||||
 | 
			
		||||
        // Fail the request if we go past the end of the buffer.
 | 
			
		||||
        if self.0.pos > self.0.end {
 | 
			
		||||
            Err(fmt::Error)
 | 
			
		||||
        } else {
 | 
			
		||||
            Ok(())
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue