@@ -376,6 +376,68 @@ impl<'s> CheckedHrpstring<'s> {
376376 #[ inline]
377377 pub fn data_part_ascii_no_checksum ( & self ) -> & ' s [ u8 ] { self . ascii }
378378
379+ /// Attempts to remove the first byte of the data part, treating it as a witness version.
380+ ///
381+ /// If [`Self::witness_version`] succeeds this function removes the first character (witness
382+ /// version byte) from the internal ASCII data part buffer. Future calls to
383+ /// [`Self::data_part_ascii_no_checksum`] will no longer include it.
384+ ///
385+ /// # Examples
386+ ///
387+ /// ```
388+ /// use bech32::{primitives::decode::CheckedHrpstring, Bech32, Fe32};
389+ ///
390+ /// let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
391+ /// let ascii = "ar0srrr7xfkvy5l643lydnw9re59gtzz";
392+ ///
393+ /// let mut checked = CheckedHrpstring::new::<Bech32>(&addr).unwrap();
394+ /// let witness_version = checked.remove_witness_version().unwrap();
395+ /// assert_eq!(witness_version, Fe32::Q);
396+ /// assert!(checked.data_part_ascii_no_checksum().iter().eq(ascii.as_bytes().iter()))
397+ /// ```
398+ #[ inline]
399+ pub fn remove_witness_version ( & mut self ) -> Option < Fe32 > {
400+ self . witness_version ( ) . map ( |witver| {
401+ self . ascii = & self . ascii [ 1 ..] ; // Remove the witness version byte.
402+ witver
403+ } )
404+ }
405+
406+ /// Returns the segwit witness version if there is one.
407+ ///
408+ /// Attempts to convert the first character of the data part to a witness version. If this
409+ /// succeeds, and it is a valid version (0..16 inclusive) we return it, otherwise `None`.
410+ ///
411+ /// Future calls to [`Self::data_part_ascii_no_checksum`] will still include the witness
412+ /// version, use [`Self::remove_witness_version`] to remove it.
413+ ///
414+ /// This function makes no guarantees on the validity of the checksum.
415+ ///
416+ /// # Examples
417+ ///
418+ /// ```
419+ /// use bech32::{primitives::decode::CheckedHrpstring, Bech32, Fe32};
420+ ///
421+ /// let addr = "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq";
422+ ///
423+ /// let checked = CheckedHrpstring::new::<Bech32>(&addr).unwrap();
424+ /// assert_eq!(checked.witness_version(), Some(Fe32::Q));
425+ /// ```
426+ #[ inline]
427+ pub fn witness_version ( & self ) -> Option < Fe32 > {
428+ let data_part = self . data_part_ascii_no_checksum ( ) ;
429+ if data_part. is_empty ( ) {
430+ return None ;
431+ }
432+
433+ // unwrap ok because we know we gave valid bech32 characters.
434+ let witness_version = Fe32 :: from_char ( data_part[ 0 ] . into ( ) ) . unwrap ( ) ;
435+ if witness_version. to_u8 ( ) > 16 {
436+ return None ;
437+ }
438+ Some ( witness_version)
439+ }
440+
379441 /// Returns an iterator that yields the data part of the parsed bech32 encoded string as [`Fe32`]s.
380442 ///
381443 /// Converts the ASCII bytes representing field elements to the respective field elements.
0 commit comments