You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: rnglists.rs
    path of file: ./repos/gimli/src/read
    
    the code of the file until where you have to start completion: use crate::common::{
    DebugAddrBase, DebugAddrIndex, DebugRngListsBase, DebugRngListsIndex, DwarfFileType, Encoding,
    RangeListsOffset, SectionId,
};
use crate::constants;
use crate::endianity::Endianity;
use crate::read::{
    lists::ListsHeader, DebugAddr, EndianSlice, Error, Reader, ReaderOffset, ReaderOffsetId,
    Result, Section,
};

/// The raw contents of the `.debug_ranges` section.
#[derive(Debug, Default, Clone, Copy)]
pub struct DebugRanges<R> {
    pub(crate) section: R,
}

impl<'input, Endian> DebugRanges<EndianSlice<'input, Endian>>
where
    Endian: Endianity,
{
    /// Construct a new `DebugRanges` instance from the data in the `.debug_ranges`
    /// section.
    ///
    /// It is the caller's responsibility to read the `.debug_ranges` section and
    /// present it as a `&[u8]` slice. That means using some ELF loader on
    /// Linux, a Mach-O loader on macOS, etc.
    ///
    /// ```
    /// use gimli::{DebugRanges, LittleEndian};
    ///
    /// # let buf = [0x00, 0x01, 0x02, 0x03];
    /// # let read_debug_ranges_section_somehow = || &buf;
    /// let debug_ranges = DebugRanges::new(read_debug_ranges_section_somehow(), LittleEndian);
    /// ```
    pub fn new(section: &'input [u8], endian: Endian) -> Self {
        Self::from(EndianSlice::new(section, endian))
    }
}

impl<R> Section<R> for DebugRanges<R> {
    fn id() -> SectionId {
        SectionId::DebugRanges
    }

    fn reader(&self) -> &R {
        &self.section
    }
}

impl<R> From<R> for DebugRanges<R> {
    fn from(section: R) -> Self {
        DebugRanges { section }
    }
}

/// The `DebugRngLists` struct represents the contents of the
/// `.debug_rnglists` section.
#[derive(Debug, Default, Clone, Copy)]
pub struct DebugRngLists<R> {
    section: R,
}

impl<'input, Endian> DebugRngLists<EndianSlice<'input, Endian>>
where
    Endian: Endianity,
{
    /// Construct a new `DebugRngLists` instance from the data in the
    /// `.debug_rnglists` section.
    ///
    /// It is the caller's responsibility to read the `.debug_rnglists`
    /// section and present it as a `&[u8]` slice. That means using some ELF
    /// loader on Linux, a Mach-O loader on macOS, etc.
    ///
    /// ```
    /// use gimli::{DebugRngLists, LittleEndian};
    ///
    /// # let buf = [0x00, 0x01, 0x02, 0x03];
    /// # let read_debug_rnglists_section_somehow = || &buf;
    /// let debug_rnglists =
    ///     DebugRngLists::new(read_debug_rnglists_section_somehow(), LittleEndian);
    /// ```
    pub fn new(section: &'input [u8], endian: Endian) -> Self {
        Self::from(EndianSlice::new(section, endian))
    }
}

impl<R> Section<R> for DebugRngLists<R> {
    fn id() -> SectionId {
        SectionId::DebugRngLists
    }

    fn reader(&self) -> &R {
        &self.section
    }
}

impl<R> From<R> for DebugRngLists<R> {
    fn from(section: R) -> Self {
        DebugRngLists { section }
    }
}

#[allow(unused)]
pub(crate) type RngListsHeader = ListsHeader;

impl<Offset> DebugRngListsBase<Offset>
where
    Offset: ReaderOffset,
{
    /// Returns a `DebugRngListsBase` with the default value of DW_AT_rnglists_base
    /// for the given `Encoding` and `DwarfFileType`.
    pub fn default_for_encoding_and_file(
        encoding: Encoding,
        file_type: DwarfFileType,
    ) -> DebugRngListsBase<Offset> {
        if encoding.version >= 5 && file_type == DwarfFileType::Dwo {
            // In .dwo files, the compiler omits the DW_AT_rnglists_base attribute (because there is
            // only a single unit in the file) but we must skip past the header, which the attribute
            // would normally do for us.
            DebugRngListsBase(Offset::from_u8(RngListsHeader::size_for_encoding(encoding)))
        } else {
            DebugRngListsBase(Offset::from_u8(0))
        }
    }
}

/// The DWARF data found in `.debug_ranges` and `.debug_rnglists` sections.
#[derive(Debug, Default, Clone, Copy)]
pub struct RangeLists<R> {
    debug_ranges: DebugRang
    
    fn test_rnglists_64() {
        let tombstone = !0u64;
        let encoding = Encoding {
            format: Format::Dwarf64,
            version: 5,
            address_size: 8,
        };
        let section = Section::with_endian(Endian::Little)
            .L64(0x0300_0000)
            .L64(0x0301_0300)
            .L64(0x0301_0400)
            .L64(0x0301_0500)
            .L64(tombstone)
            .L64(0x0301_0600);
        let buf = section.get_contents().unwrap();
        let debug_addr = &DebugAddr::from(EndianSlice::new(&buf, LittleEndian));
        let debug_addr_base = DebugAddrBase(0);

        let start = Label::new();
        let first = Label::new();
        let size = Label::new();
        #[rustfmt::skip]
        let section = Section::with_endian(Endian::Little)
            // Header
            .mark(&start)
            .L32(0xffff_ffff)
            .L64(&size)
            .L16(encoding.version)
            .L8(encoding.address_size)
            .L8(0)
            .L32(0)
            .mark(&first)
            // An OffsetPair using the unit base address.
            .L8(4).uleb(0x10200).uleb(0x10300)
            // A base address selection followed by an OffsetPair.
            .L8(5).L64(0x0200_0000)
            .L8(4).uleb(0x10400).uleb(0x10500)
            // An empty OffsetPair followed by a normal OffsetPair.
            .L8(4).uleb(0x10600).uleb(0x10600)
            .L8(4).uleb(0x10800).uleb(0x10900)
            // A StartEnd
            .L8(6).L64(0x201_0a00).L64(0x201_0b00)
            // A StartLength
            .L8(7).L64(0x201_0c00).uleb(0x100)
            // An OffsetPair that starts at 0.
            .L8(4).uleb(0).uleb(1)
            // An OffsetPair that starts and ends at 0.
            .L8(4).uleb(0).uleb(0)
            // An OffsetPair that ends at -1.
            .L8(5).L64(0)
            .L8(4).uleb(0).uleb(0xffff_ffff)
            // A BaseAddressx + OffsetPair
            .L8(1).uleb(0)
            .L8(4).uleb(0x10100).uleb(0x10200)
            // A StartxEndx
            .L8(2).uleb(1).uleb(2)
            // A StartxLength
            .L8(3).uleb(3).uleb(0x100)

            // Tombstone entries, all of which should be ignored.
            // A BaseAddressx that is a tombstone.
            .L8(1).uleb(4)
            .L8(4).uleb(0x11100).uleb(0x11200)
            // A BaseAddress that is a tombstone.
            .L8(5).L64(tombstone)
            .L8(4).uleb(0x11300).uleb(0x11400)
            // A StartxEndx that is a tombstone.
            .L8(2).uleb(4).uleb(5)
            // A StartxLength that is a tombstone.
            .L8(3).uleb(4).uleb(0x100)
            // A StartEnd that is a tombstone.
            .L8(6).L64(tombstone).L64(0x201_1500)
            // A StartLength that is a tombstone.
            .L8(7).L64(tombstone).uleb(0x100)
            // A StartEnd (not ignored)
            .L8(6).L64(0x201_1600).L64(0x201_1700)

            // A range end.
            .L8(0)
            // Some extra data.
            .L32(0xffff_ffff);
        size.set_const((&section.here() - &start - 12) as u64);

        let buf = section.get_contents().unwrap();
        let debug_ranges = DebugRanges::new(&[], LittleEndian);
        let debug_rnglists = DebugRngLists::new(&buf, LittleEndian);
        let rnglists = RangeLists::new(debug_ranges, debug_rnglists);
        let offset = RangeListsOffset((&first - &start) as usize);
        let mut ranges = rnglists
            .ranges(offset, encoding, 0x0100_0000, debug_addr, debug_addr_base)
            .unwrap();

        // A normal range.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0101_0200,
                end: 0x0101_0300,
            }))
        );

        // A base address selection followed by a normal range.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0201_0400,
                end: 0x0201_0500,
            }))
        );

        // An empty range followed by a normal range.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0201_0600,
                end: 0x0201_0600,
            }))
        );
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0201_0800,
                end: 0x0201_0900,
            }))
        );

        // A normal range.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0201_0a00,
                end: 0x0201_0b00,
            }))
        );

        // A normal range.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0201_0c00,
                end: 0x0201_0d00,
            }))
        );

        // A range that starts at 0.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0200_0000,
                end: 0x0200_0001,
            }))
        );

        // A range that starts and ends at 0.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0200_0000,
                end: 0x0200_0000,
            }))
        );

        // A range that ends at -1.
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0000_0000,
                end: 0xffff_ffff,
            }))
        );

        // A BaseAddressx + OffsetPair
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0301_0100,
                end: 0x0301_0200,
            }))
        );

        // A StartxEndx
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0301_0300,
                end: 0x0301_0400,
            }))
        );

        // A StartxLength
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0301_0500,
                end: 0x0301_0600,
            }))
        );

        // A StartEnd range following the tombstones
        assert_eq!(
            ranges.next(),
            Ok(Some(Range {
                begin: 0x0201_1600,
                end: 0x0201_1700,
            }))
        );

        // A range end.
        assert_eq!(ranges.next(), Ok(None));

        // An offset at the end of buf.
        let mut ranges = rnglists
            .ranges(
                RangeListsOffset(buf.len()),
                encoding,
                0x0100_0000,
                debug_addr,
                debug_addr_base,
            )
            .unwrap();
        assert_eq!(ranges.next(), Ok(None));
    }