//! PDF Name type.
//!
//! PDF names are atomic symbols uniquely defined by a sequence of bytes.
//! They are used as keys in dictionaries, operator identifiers, and
//! resource names. This module provides the [`Name`] type with predefined
//! constants for commonly used PDF names.

use std::fmt;

/// A PDF name object.
///
/// PDF names are byte sequences (not necessarily valid UTF-8) that serve as
/// atomic symbols. In the PDF file they are written with a leading `/`
/// (e.g., `/Type`, `/Length`), but the leading slash is not stored in the
/// name's byte representation.
///
/// # Examples
///
/// ```
/// use rpdfium_core::Name;
///
/// let name = Name::from_bytes(b"Type".to_vec());
/// assert_eq!(name.as_bytes(), b"Type");
/// assert_eq!(name.as_str().as_ref(), "Type");
/// ```
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Name {
    bytes: Vec<u8>,
}

impl Name {
    /// Create a `Name` from raw bytes.
    ///
    /// The bytes should not include the leading `/` delimiter.
    pub fn from_bytes(bytes: Vec<u8>) -> Self {
        Self { bytes }
    }

    /// Return the raw bytes of this name.
    pub fn as_bytes(&self) -> &[u8] {
        &self.bytes
    }

    /// Return the name as a UTF-8 string.
    ///
    /// Most PDF names are valid ASCII/UTF-8. This performs a lossy conversion,
    /// replacing invalid UTF-8 sequences with U+FFFD.
    pub fn as_str(&self) -> std::borrow::Cow<'_, str> {
        String::from_utf8_lossy(&self.bytes)
    }
}

impl fmt::Debug for Name {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Name(/")?;
        for &b in &self.bytes {
            if b.is_ascii_graphic() && b != b'/' {
                write!(f, "{}", b as char)?;
            } else {
                write!(f, "#{b:02X}")?;
            }
        }
        write!(f, ")")
    }
}

impl fmt::Display for Name {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "/{}", self.as_str())
    }
}

impl From<&str> for Name {
    fn from(s: &str) -> Self {
        Self::from_bytes(s.as_bytes().to_vec())
    }
}

impl From<&[u8]> for Name {
    fn from(bytes: &[u8]) -> Self {
        Self::from_bytes(bytes.to_vec())
    }
}

// ---------------------------------------------------------------------------
// Predefined Name Constants
// ---------------------------------------------------------------------------

impl Name {
    // --- General structure ---

    /// `/Type`
    pub fn r#type() -> Self {
        Self::from_bytes(b"Type".to_vec())
    }
    /// `/Subtype`
    pub fn subtype() -> Self {
        Self::from_bytes(b"Subtype".to_vec())
    }
    /// `/Length`
    pub fn length() -> Self {
        Self::from_bytes(b"Length".to_vec())
    }
    /// `/Filter`
    pub fn filter() -> Self {
        Self::from_bytes(b"Filter".to_vec())
    }
    /// `/DecodeParms`
    pub fn decode_parms() -> Self {
        Self::from_bytes(b"DecodeParms".to_vec())
    }

    // --- Cross-reference and trailer ---

    /// `/Size`
    pub fn size() -> Self {
        Self::from_bytes(b"Size".to_vec())
    }
    /// `/Root`
    pub fn root() -> Self {
        Self::from_bytes(b"Root".to_vec())
    }
    /// `/Info`
    pub fn info() -> Self {
        Self::from_bytes(b"Info".to_vec())
    }
    /// `/ID`
    pub fn id() -> Self {
        Self::from_bytes(b"ID".to_vec())
    }
    /// `/Prev`
    pub fn prev() -> Self {
        Self::from_bytes(b"Prev".to_vec())
    }
    /// `/Encrypt`
    pub fn encrypt() -> Self {
        Self::from_bytes(b"Encrypt".to_vec())
    }
    /// `/W`
    pub fn w() -> Self {
        Self::from_bytes(b"W".to_vec())
    }
    /// `/Index`
    pub fn index() -> Self {
        Self::from_bytes(b"Index".to_vec())
    }
    /// `/XRefStm`
    pub fn xref_stm() -> Self {
        Self::from_bytes(b"XRefStm".to_vec())
    }

    // --- Pages ---

    /// `/Pages`
    pub fn pages() -> Self {
        Self::from_bytes(b"Pages".to_vec())
    }
    /// `/Page`
    pub fn page() -> Self {
        Self::from_bytes(b"Page".to_vec())
    }
    /// `/Kids`
    pub fn kids() -> Self {
        Self::from_bytes(b"Kids".to_vec())
    }
    /// `/Count`
    pub fn count() -> Self {
        Self::from_bytes(b"Count".to_vec())
    }
    /// `/Parent`
    pub fn parent() -> Self {
        Self::from_bytes(b"Parent".to_vec())
    }
    /// `/MediaBox`
    pub fn media_box() -> Self {
        Self::from_bytes(b"MediaBox".to_vec())
    }
    /// `/CropBox`
    pub fn crop_box() -> Self {
        Self::from_bytes(b"CropBox".to_vec())
    }
    /// `/BleedBox`
    pub fn bleed_box() -> Self {
        Self::from_bytes(b"BleedBox".to_vec())
    }
    /// `/TrimBox`
    pub fn trim_box() -> Self {
        Self::from_bytes(b"TrimBox".to_vec())
    }
    /// `/ArtBox`
    pub fn art_box() -> Self {
        Self::from_bytes(b"ArtBox".to_vec())
    }
    /// `/Rotate`
    pub fn rotate() -> Self {
        Self::from_bytes(b"Rotate".to_vec())
    }
    /// `/Contents`
    pub fn contents() -> Self {
        Self::from_bytes(b"Contents".to_vec())
    }
    /// `/Resources`
    pub fn resources() -> Self {
        Self::from_bytes(b"Resources".to_vec())
    }
    /// `/Annots`
    pub fn annots() -> Self {
        Self::from_bytes(b"Annots".to_vec())
    }

    // --- Resources ---

    /// `/Font`
    pub fn font() -> Self {
        Self::from_bytes(b"Font".to_vec())
    }
    /// `/XObject`
    pub fn x_object() -> Self {
        Self::from_bytes(b"XObject".to_vec())
    }
    /// `/ExtGState`
    pub fn ext_g_state() -> Self {
        Self::from_bytes(b"ExtGState".to_vec())
    }
    /// `/ColorSpace`
    pub fn color_space() -> Self {
        Self::from_bytes(b"ColorSpace".to_vec())
    }
    /// `/Pattern`
    pub fn pattern() -> Self {
        Self::from_bytes(b"Pattern".to_vec())
    }
    /// `/Shading`
    pub fn shading() -> Self {
        Self::from_bytes(b"Shading".to_vec())
    }
    /// `/Properties`
    pub fn properties() -> Self {
        Self::from_bytes(b"Properties".to_vec())
    }

    // --- Fonts ---

    /// `/BaseFont`
    pub fn base_font() -> Self {
        Self::from_bytes(b"BaseFont".to_vec())
    }
    /// `/Encoding`
    pub fn encoding() -> Self {
        Self::from_bytes(b"Encoding".to_vec())
    }
    /// `/FirstChar`
    pub fn first_char() -> Self {
        Self::from_bytes(b"FirstChar".to_vec())
    }
    /// `/LastChar`
    pub fn last_char() -> Self {
        Self::from_bytes(b"LastChar".to_vec())
    }
    /// `/Widths`
    pub fn widths() -> Self {
        Self::from_bytes(b"Widths".to_vec())
    }
    /// `/FontDescriptor`
    pub fn font_descriptor() -> Self {
        Self::from_bytes(b"FontDescriptor".to_vec())
    }
    /// `/ToUnicode`
    pub fn to_unicode() -> Self {
        Self::from_bytes(b"ToUnicode".to_vec())
    }
    /// `/DescendantFonts`
    pub fn descendant_fonts() -> Self {
        Self::from_bytes(b"DescendantFonts".to_vec())
    }

    // --- Filters ---

    /// `/FlateDecode`
    pub fn flate_decode() -> Self {
        Self::from_bytes(b"FlateDecode".to_vec())
    }
    /// `/DCTDecode`
    pub fn dct_decode() -> Self {
        Self::from_bytes(b"DCTDecode".to_vec())
    }
    /// `/LZWDecode`
    pub fn lzw_decode() -> Self {
        Self::from_bytes(b"LZWDecode".to_vec())
    }
    /// `/ASCIIHexDecode`
    pub fn ascii_hex_decode() -> Self {
        Self::from_bytes(b"ASCIIHexDecode".to_vec())
    }
    /// `/ASCII85Decode`
    pub fn ascii85_decode() -> Self {
        Self::from_bytes(b"ASCII85Decode".to_vec())
    }
    /// `/RunLengthDecode`
    pub fn run_length_decode() -> Self {
        Self::from_bytes(b"RunLengthDecode".to_vec())
    }
    /// `/CCITTFaxDecode`
    pub fn ccitt_fax_decode() -> Self {
        Self::from_bytes(b"CCITTFaxDecode".to_vec())
    }
    /// `/JBIG2Decode`
    pub fn jbig2_decode() -> Self {
        Self::from_bytes(b"JBIG2Decode".to_vec())
    }
    /// `/JPXDecode`
    pub fn jpx_decode() -> Self {
        Self::from_bytes(b"JPXDecode".to_vec())
    }
    /// `/Crypt`
    pub fn crypt() -> Self {
        Self::from_bytes(b"Crypt".to_vec())
    }

    // --- Filter abbreviations ---

    /// `/Fl` (abbreviation for FlateDecode)
    pub fn fl() -> Self {
        Self::from_bytes(b"Fl".to_vec())
    }
    /// `/A85` (abbreviation for ASCII85Decode)
    pub fn a85() -> Self {
        Self::from_bytes(b"A85".to_vec())
    }
    /// `/AHx` (abbreviation for ASCIIHexDecode)
    pub fn ahx() -> Self {
        Self::from_bytes(b"AHx".to_vec())
    }
    /// `/RL` (abbreviation for RunLengthDecode)
    pub fn rl() -> Self {
        Self::from_bytes(b"RL".to_vec())
    }
    /// `/CCF` (abbreviation for CCITTFaxDecode)
    pub fn ccf() -> Self {
        Self::from_bytes(b"CCF".to_vec())
    }

    // --- Filter parameters ---

    /// `/Predictor`
    pub fn predictor() -> Self {
        Self::from_bytes(b"Predictor".to_vec())
    }
    /// `/Columns`
    pub fn columns() -> Self {
        Self::from_bytes(b"Columns".to_vec())
    }
    /// `/Colors`
    pub fn colors() -> Self {
        Self::from_bytes(b"Colors".to_vec())
    }
    /// `/EarlyChange`
    pub fn early_change() -> Self {
        Self::from_bytes(b"EarlyChange".to_vec())
    }
    /// `/K` (CCITT K parameter)
    pub fn k() -> Self {
        Self::from_bytes(b"K".to_vec())
    }
    /// `/EndOfLine`
    pub fn end_of_line() -> Self {
        Self::from_bytes(b"EndOfLine".to_vec())
    }
    /// `/EncodedByteAlign`
    pub fn encoded_byte_align() -> Self {
        Self::from_bytes(b"EncodedByteAlign".to_vec())
    }
    /// `/BlackIs1`
    pub fn black_is_1() -> Self {
        Self::from_bytes(b"BlackIs1".to_vec())
    }

    // --- Images ---

    /// `/Width`
    pub fn width() -> Self {
        Self::from_bytes(b"Width".to_vec())
    }
    /// `/Height`
    pub fn height() -> Self {
        Self::from_bytes(b"Height".to_vec())
    }
    /// `/BitsPerComponent`
    pub fn bits_per_component() -> Self {
        Self::from_bytes(b"BitsPerComponent".to_vec())
    }
    /// `/ImageMask`
    pub fn image_mask() -> Self {
        Self::from_bytes(b"ImageMask".to_vec())
    }
    /// `/Mask`
    pub fn mask() -> Self {
        Self::from_bytes(b"Mask".to_vec())
    }
    /// `/SMask`
    pub fn s_mask() -> Self {
        Self::from_bytes(b"SMask".to_vec())
    }

    // --- Catalog ---

    /// `/Catalog`
    pub fn catalog() -> Self {
        Self::from_bytes(b"Catalog".to_vec())
    }
    /// `/Outlines`
    pub fn outlines() -> Self {
        Self::from_bytes(b"Outlines".to_vec())
    }
    /// `/Dests`
    pub fn dests() -> Self {
        Self::from_bytes(b"Dests".to_vec())
    }
    /// `/Names`
    pub fn names() -> Self {
        Self::from_bytes(b"Names".to_vec())
    }
    /// `/EmbeddedFiles`
    pub fn embedded_files() -> Self {
        Self::from_bytes(b"EmbeddedFiles".to_vec())
    }
    /// `/AcroForm`
    pub fn acro_form() -> Self {
        Self::from_bytes(b"AcroForm".to_vec())
    }
    /// `/Metadata`
    pub fn metadata() -> Self {
        Self::from_bytes(b"Metadata".to_vec())
    }

    // --- Object streams ---

    /// `/ObjStm`
    pub fn obj_stm() -> Self {
        Self::from_bytes(b"ObjStm".to_vec())
    }
    /// `/N` (number of objects in an object stream)
    pub fn n() -> Self {
        Self::from_bytes(b"N".to_vec())
    }
    /// `/First` (byte offset of first object in object stream)
    pub fn first() -> Self {
        Self::from_bytes(b"First".to_vec())
    }

    /// `/Matrix`
    pub fn matrix() -> Self {
        Self::from_bytes(b"Matrix".to_vec())
    }

    /// `/Rows`
    pub fn rows() -> Self {
        Self::from_bytes(b"Rows".to_vec())
    }

    // --- Transparency / Group ---

    /// `/Group`
    pub fn group() -> Self {
        Self::from_bytes(b"Group".to_vec())
    }
    /// `/I` (Isolated flag)
    pub fn i() -> Self {
        Self::from_bytes(b"I".to_vec())
    }
    /// `/G` (SMask group stream)
    pub fn g() -> Self {
        Self::from_bytes(b"G".to_vec())
    }
    /// `/BC` (Backdrop color)
    pub fn bc() -> Self {
        Self::from_bytes(b"BC".to_vec())
    }
    /// `/TR` (Transfer function)
    pub fn tr() -> Self {
        Self::from_bytes(b"TR".to_vec())
    }
    /// `/AIS` (Alpha is shape)
    pub fn ais() -> Self {
        Self::from_bytes(b"AIS".to_vec())
    }
    /// `/TK` (Text knockout)
    pub fn tk() -> Self {
        Self::from_bytes(b"TK".to_vec())
    }
    /// `/SA` (Stroke adjustment)
    pub fn sa() -> Self {
        Self::from_bytes(b"SA".to_vec())
    }
    /// `/HT` (Halftone)
    pub fn ht() -> Self {
        Self::from_bytes(b"HT".to_vec())
    }
    /// `/S` (various: subtype, style)
    pub fn s() -> Self {
        Self::from_bytes(b"S".to_vec())
    }
    /// `/CS` (color space in transparency group)
    pub fn cs() -> Self {
        Self::from_bytes(b"CS".to_vec())
    }

    // --- Document metadata ---

    /// `/Title`
    pub fn title() -> Self {
        Self::from_bytes(b"Title".to_vec())
    }
    /// `/Author`
    pub fn author() -> Self {
        Self::from_bytes(b"Author".to_vec())
    }
    /// `/Subject`
    pub fn subject() -> Self {
        Self::from_bytes(b"Subject".to_vec())
    }
    /// `/Keywords`
    pub fn keywords() -> Self {
        Self::from_bytes(b"Keywords".to_vec())
    }
    /// `/Creator`
    pub fn creator() -> Self {
        Self::from_bytes(b"Creator".to_vec())
    }
    /// `/Producer`
    pub fn producer() -> Self {
        Self::from_bytes(b"Producer".to_vec())
    }
    /// `/CreationDate`
    pub fn creation_date() -> Self {
        Self::from_bytes(b"CreationDate".to_vec())
    }
    /// `/ModDate`
    pub fn mod_date() -> Self {
        Self::from_bytes(b"ModDate".to_vec())
    }

    // --- Bookmarks / Outlines ---

    /// `/Next`
    pub fn next() -> Self {
        Self::from_bytes(b"Next".to_vec())
    }
    /// `/Last`
    pub fn last() -> Self {
        Self::from_bytes(b"Last".to_vec())
    }
    /// `/Dest`
    pub fn dest() -> Self {
        Self::from_bytes(b"Dest".to_vec())
    }
    /// `/A` (Action)
    pub fn a() -> Self {
        Self::from_bytes(b"A".to_vec())
    }
    /// `/D` (Destination array)
    pub fn d() -> Self {
        Self::from_bytes(b"D".to_vec())
    }
    /// `/URI`
    pub fn uri() -> Self {
        Self::from_bytes(b"URI".to_vec())
    }
    /// `/Open`
    pub fn open() -> Self {
        Self::from_bytes(b"Open".to_vec())
    }

    // --- Page labels / Number trees ---

    /// `/PageLabels`
    pub fn page_labels() -> Self {
        Self::from_bytes(b"PageLabels".to_vec())
    }
    /// `/Nums`
    pub fn nums() -> Self {
        Self::from_bytes(b"Nums".to_vec())
    }
    /// `/Limits`
    pub fn limits() -> Self {
        Self::from_bytes(b"Limits".to_vec())
    }
    /// `/St` (Start value for page labels)
    pub fn st() -> Self {
        Self::from_bytes(b"St".to_vec())
    }
    /// `/P` (Prefix for page labels)
    pub fn p() -> Self {
        Self::from_bytes(b"P".to_vec())
    }
    /// `/SE` (Structure element)
    pub fn se() -> Self {
        Self::from_bytes(b"SE".to_vec())
    }

    // --- Color spaces ---

    /// `/Alternate`
    pub fn alternate() -> Self {
        Self::from_bytes(b"Alternate".to_vec())
    }
    /// `/Range`
    pub fn range() -> Self {
        Self::from_bytes(b"Range".to_vec())
    }
    /// `/WhitePoint`
    pub fn white_point() -> Self {
        Self::from_bytes(b"WhitePoint".to_vec())
    }
    /// `/BlackPoint`
    pub fn black_point() -> Self {
        Self::from_bytes(b"BlackPoint".to_vec())
    }
    /// `/Gamma`
    pub fn gamma() -> Self {
        Self::from_bytes(b"Gamma".to_vec())
    }
    /// `/CalGray`
    pub fn cal_gray() -> Self {
        Self::from_bytes(b"CalGray".to_vec())
    }
    /// `/CalRGB`
    pub fn cal_rgb() -> Self {
        Self::from_bytes(b"CalRGB".to_vec())
    }
    /// `/Lab`
    pub fn lab() -> Self {
        Self::from_bytes(b"Lab".to_vec())
    }
    /// `/ICCBased`
    pub fn icc_based() -> Self {
        Self::from_bytes(b"ICCBased".to_vec())
    }
    /// `/Indexed`
    pub fn indexed() -> Self {
        Self::from_bytes(b"Indexed".to_vec())
    }
    /// `/Separation`
    pub fn separation() -> Self {
        Self::from_bytes(b"Separation".to_vec())
    }
    /// `/DeviceN`
    pub fn device_n() -> Self {
        Self::from_bytes(b"DeviceN".to_vec())
    }
    /// `/DeviceGray`
    pub fn device_gray() -> Self {
        Self::from_bytes(b"DeviceGray".to_vec())
    }
    /// `/DeviceRGB`
    pub fn device_rgb() -> Self {
        Self::from_bytes(b"DeviceRGB".to_vec())
    }
    /// `/DeviceCMYK`
    pub fn device_cmyk() -> Self {
        Self::from_bytes(b"DeviceCMYK".to_vec())
    }

    // --- Font (CID / Type 3) ---

    /// `/CIDToGIDMap`
    pub fn cid_to_gid_map() -> Self {
        Self::from_bytes(b"CIDToGIDMap".to_vec())
    }
    /// `/WMode`
    pub fn w_mode() -> Self {
        Self::from_bytes(b"WMode".to_vec())
    }
    /// `/W2`
    pub fn w2() -> Self {
        Self::from_bytes(b"W2".to_vec())
    }
    /// `/DW`
    pub fn dw() -> Self {
        Self::from_bytes(b"DW".to_vec())
    }
    /// `/DW2`
    pub fn dw2() -> Self {
        Self::from_bytes(b"DW2".to_vec())
    }
    /// `/CIDSystemInfo`
    pub fn cid_system_info() -> Self {
        Self::from_bytes(b"CIDSystemInfo".to_vec())
    }
    /// `/Registry`
    pub fn registry() -> Self {
        Self::from_bytes(b"Registry".to_vec())
    }
    /// `/Ordering`
    pub fn ordering() -> Self {
        Self::from_bytes(b"Ordering".to_vec())
    }
    /// `/Supplement`
    pub fn supplement() -> Self {
        Self::from_bytes(b"Supplement".to_vec())
    }
    /// `/CharProcs`
    pub fn char_procs() -> Self {
        Self::from_bytes(b"CharProcs".to_vec())
    }
    /// `/FontMatrix`
    pub fn font_matrix() -> Self {
        Self::from_bytes(b"FontMatrix".to_vec())
    }
    /// `/Identity`
    pub fn identity() -> Self {
        Self::from_bytes(b"Identity".to_vec())
    }
    /// `/Identity-H`
    pub fn identity_h() -> Self {
        Self::from_bytes(b"Identity-H".to_vec())
    }
    /// `/Identity-V`
    pub fn identity_v() -> Self {
        Self::from_bytes(b"Identity-V".to_vec())
    }

    // --- Pattern / Shading ---

    /// `/PaintType`
    pub fn paint_type() -> Self {
        Self::from_bytes(b"PaintType".to_vec())
    }
    /// `/TilingType`
    pub fn tiling_type() -> Self {
        Self::from_bytes(b"TilingType".to_vec())
    }
    /// `/XStep`
    pub fn x_step() -> Self {
        Self::from_bytes(b"XStep".to_vec())
    }
    /// `/YStep`
    pub fn y_step() -> Self {
        Self::from_bytes(b"YStep".to_vec())
    }
    /// `/ShadingType`
    pub fn shading_type() -> Self {
        Self::from_bytes(b"ShadingType".to_vec())
    }
    /// `/Coords`
    pub fn coords() -> Self {
        Self::from_bytes(b"Coords".to_vec())
    }
    /// `/Domain`
    pub fn domain() -> Self {
        Self::from_bytes(b"Domain".to_vec())
    }
    /// `/Function`
    pub fn function() -> Self {
        Self::from_bytes(b"Function".to_vec())
    }
    /// `/Extend`
    pub fn extend() -> Self {
        Self::from_bytes(b"Extend".to_vec())
    }
    /// `/Background`
    pub fn background() -> Self {
        Self::from_bytes(b"Background".to_vec())
    }
    /// `/BitsPerCoordinate`
    pub fn bits_per_coordinate() -> Self {
        Self::from_bytes(b"BitsPerCoordinate".to_vec())
    }
    /// `/BitsPerFlag`
    pub fn bits_per_flag() -> Self {
        Self::from_bytes(b"BitsPerFlag".to_vec())
    }
    /// `/VerticesPerRow`
    pub fn vertices_per_row() -> Self {
        Self::from_bytes(b"VerticesPerRow".to_vec())
    }
    /// `/BBox`
    pub fn b_box() -> Self {
        Self::from_bytes(b"BBox".to_vec())
    }

    // --- PDF Functions ---

    /// `/FunctionType`
    pub fn function_type() -> Self {
        Self::from_bytes(b"FunctionType".to_vec())
    }
    /// `/C0`
    pub fn c0() -> Self {
        Self::from_bytes(b"C0".to_vec())
    }
    /// `/C1`
    pub fn c1() -> Self {
        Self::from_bytes(b"C1".to_vec())
    }

    // --- Annotations ---

    /// `Annot` (annotation /Type value)
    pub fn annot() -> Self {
        Self::from_bytes(b"Annot".to_vec())
    }
    /// `/AP` (Appearance)
    pub fn ap() -> Self {
        Self::from_bytes(b"AP".to_vec())
    }
    /// `/NM` (Annotation name)
    pub fn nm() -> Self {
        Self::from_bytes(b"NM".to_vec())
    }
    /// `/F` (Flags)
    pub fn f() -> Self {
        Self::from_bytes(b"F".to_vec())
    }
    /// `/C` (Color)
    pub fn c() -> Self {
        Self::from_bytes(b"C".to_vec())
    }
    /// `/Border`
    pub fn border() -> Self {
        Self::from_bytes(b"Border".to_vec())
    }
    /// `/BS` (Border style)
    pub fn bs() -> Self {
        Self::from_bytes(b"BS".to_vec())
    }
    /// `/Popup`
    pub fn popup() -> Self {
        Self::from_bytes(b"Popup".to_vec())
    }
    /// `/T` (Title / text)
    pub fn t() -> Self {
        Self::from_bytes(b"T".to_vec())
    }
    /// `/Subj` (Subject)
    pub fn subj() -> Self {
        Self::from_bytes(b"Subj".to_vec())
    }
    /// `/RC` (Rich content)
    pub fn rc() -> Self {
        Self::from_bytes(b"RC".to_vec())
    }
    /// `/IT` (Intent)
    pub fn it() -> Self {
        Self::from_bytes(b"IT".to_vec())
    }
    /// `/Rect`
    pub fn rect() -> Self {
        Self::from_bytes(b"Rect".to_vec())
    }
    /// `/QuadPoints`
    pub fn quad_points() -> Self {
        Self::from_bytes(b"QuadPoints".to_vec())
    }
    /// `/L` (Line endpoints)
    pub fn l() -> Self {
        Self::from_bytes(b"L".to_vec())
    }
    /// `/LL` (Leader line length)
    pub fn ll() -> Self {
        Self::from_bytes(b"LL".to_vec())
    }
    /// `/Vertices` (Polygon/PolyLine vertices)
    pub fn vertices() -> Self {
        Self::from_bytes(b"Vertices".to_vec())
    }
    /// `/InkList` (Ink annotation stroke paths)
    pub fn ink_list() -> Self {
        Self::from_bytes(b"InkList".to_vec())
    }
    /// `/DA` (Default appearance string)
    pub fn da() -> Self {
        Self::from_bytes(b"DA".to_vec())
    }
    /// `/Name` (Stamp icon name or annotation name)
    pub fn name_key() -> Self {
        Self::from_bytes(b"Name".to_vec())
    }

    // --- XObject / Form ---

    /// `/BitsPerSample`
    pub fn bits_per_sample() -> Self {
        Self::from_bytes(b"BitsPerSample".to_vec())
    }
    /// `/Form`
    pub fn form() -> Self {
        Self::from_bytes(b"Form".to_vec())
    }
    /// `/Image`
    pub fn image() -> Self {
        Self::from_bytes(b"Image".to_vec())
    }

    /// `/Encode`
    pub fn encode() -> Self {
        Self::from_bytes(b"Encode".to_vec())
    }
    /// `/Functions`
    pub fn functions() -> Self {
        Self::from_bytes(b"Functions".to_vec())
    }
    /// `/Bounds`
    pub fn bounds() -> Self {
        Self::from_bytes(b"Bounds".to_vec())
    }

    // --- Miscellaneous ---

    /// `/FlateDecode` abbreviation `/Fl` is already defined.
    /// `/Decode`
    pub fn decode() -> Self {
        Self::from_bytes(b"Decode".to_vec())
    }
    /// `/Interpolate`
    pub fn interpolate() -> Self {
        Self::from_bytes(b"Interpolate".to_vec())
    }
    /// `/Intent`
    pub fn intent() -> Self {
        Self::from_bytes(b"Intent".to_vec())
    }

    // --- Text extraction ---

    /// `/ActualText`
    pub fn actual_text() -> Self {
        Self::from_bytes(b"ActualText".to_vec())
    }

    // --- GoTo actions ---

    /// `/GoTo`
    pub fn go_to() -> Self {
        Self::from_bytes(b"GoTo".to_vec())
    }
    /// `/GoToR`
    pub fn go_to_r() -> Self {
        Self::from_bytes(b"GoToR".to_vec())
    }
    /// `/Named`
    pub fn named() -> Self {
        Self::from_bytes(b"Named".to_vec())
    }
    /// `/Launch`
    pub fn launch() -> Self {
        Self::from_bytes(b"Launch".to_vec())
    }

    // --- Appearance sub-dicts ---

    /// `/R` (Rollover appearance)
    pub fn r() -> Self {
        Self::from_bytes(b"R".to_vec())
    }

    // --- Encryption ---

    /// `/V` (Encryption version)
    pub fn v() -> Self {
        Self::from_bytes(b"V".to_vec())
    }
    /// `/O` (Owner password hash)
    pub fn o() -> Self {
        Self::from_bytes(b"O".to_vec())
    }
    /// `/U` (User password hash)
    pub fn u() -> Self {
        Self::from_bytes(b"U".to_vec())
    }
    /// `/OE` (Owner encryption key, R5/R6)
    pub fn oe() -> Self {
        Self::from_bytes(b"OE".to_vec())
    }
    /// `/UE` (User encryption key, R5/R6)
    pub fn ue() -> Self {
        Self::from_bytes(b"UE".to_vec())
    }
    /// `/CF` (Crypt filters)
    pub fn cf() -> Self {
        Self::from_bytes(b"CF".to_vec())
    }
    /// `/StmF` (Stream crypt filter name)
    pub fn stm_f() -> Self {
        Self::from_bytes(b"StmF".to_vec())
    }
    /// `/StrF` (String crypt filter name)
    pub fn str_f() -> Self {
        Self::from_bytes(b"StrF".to_vec())
    }
    /// `/CFM` (Crypt filter method)
    pub fn cfm() -> Self {
        Self::from_bytes(b"CFM".to_vec())
    }
    /// `/EncryptMetadata`
    pub fn encrypt_metadata() -> Self {
        Self::from_bytes(b"EncryptMetadata".to_vec())
    }
    /// `/StdCF` (Standard crypt filter)
    pub fn std_cf() -> Self {
        Self::from_bytes(b"StdCF".to_vec())
    }
    /// `/AuthEvent`
    pub fn auth_event() -> Self {
        Self::from_bytes(b"AuthEvent".to_vec())
    }
    /// `/Perms` (R6 permissions validation)
    pub fn perms() -> Self {
        Self::from_bytes(b"Perms".to_vec())
    }
    /// `/None` (Identity/no encryption filter)
    pub fn none() -> Self {
        Self::from_bytes(b"None".to_vec())
    }
    /// `/V2` (RC4 crypt filter method)
    pub fn v2() -> Self {
        Self::from_bytes(b"V2".to_vec())
    }
    /// `/AESV2` (AES-128 crypt filter method)
    pub fn aesv2() -> Self {
        Self::from_bytes(b"AESV2".to_vec())
    }
    /// `/AESV3` (AES-256 crypt filter method)
    pub fn aesv3() -> Self {
        Self::from_bytes(b"AESV3".to_vec())
    }
    /// `/Standard` (Standard security handler)
    pub fn standard() -> Self {
        Self::from_bytes(b"Standard".to_vec())
    }

    // --- Phase 5: JBIG2 ---

    /// `/JBIG2Globals`
    pub fn jbig2_globals() -> Self {
        Self::from_bytes(b"JBIG2Globals".to_vec())
    }

    // --- Phase 5: Optional Content ---

    /// `/OCProperties`
    pub fn oc_properties() -> Self {
        Self::from_bytes(b"OCProperties".to_vec())
    }
    /// `/OCGs`
    pub fn ocgs() -> Self {
        Self::from_bytes(b"OCGs".to_vec())
    }
    /// `/OC`
    pub fn oc() -> Self {
        Self::from_bytes(b"OC".to_vec())
    }
    /// `/BaseState`
    pub fn base_state() -> Self {
        Self::from_bytes(b"BaseState".to_vec())
    }
    /// `/ON`
    pub fn on() -> Self {
        Self::from_bytes(b"ON".to_vec())
    }
    /// `/OFF`
    pub fn off() -> Self {
        Self::from_bytes(b"OFF".to_vec())
    }
    /// `/VE`
    pub fn ve() -> Self {
        Self::from_bytes(b"VE".to_vec())
    }
    /// `/Usage`
    pub fn usage() -> Self {
        Self::from_bytes(b"Usage".to_vec())
    }

    // --- Phase 6: Type 1 Fonts ---

    /// `/FontFile` (Type 1 font stream)
    pub fn font_file() -> Self {
        Self::from_bytes(b"FontFile".to_vec())
    }
    /// `/FontFile2` (TrueType font stream)
    pub fn font_file2() -> Self {
        Self::from_bytes(b"FontFile2".to_vec())
    }
    /// `/FontFile3` (CIDFont / OpenType font stream)
    pub fn font_file3() -> Self {
        Self::from_bytes(b"FontFile3".to_vec())
    }

    // --- Phase 6: AcroForm ---

    /// `/Fields` (AcroForm fields array)
    pub fn fields() -> Self {
        Self::from_bytes(b"Fields".to_vec())
    }
    /// `/FT` (Form field type)
    pub fn ft() -> Self {
        Self::from_bytes(b"FT".to_vec())
    }
    /// `/DV` (Default value)
    pub fn dv() -> Self {
        Self::from_bytes(b"DV".to_vec())
    }
    /// `/Opt` (Choice field options)
    pub fn opt() -> Self {
        Self::from_bytes(b"Opt".to_vec())
    }
    /// `/TU` (Tooltip / alternate field description)
    pub fn tu() -> Self {
        Self::from_bytes(b"TU".to_vec())
    }
    /// `/Q` (Quadding / field alignment)
    pub fn q() -> Self {
        Self::from_bytes(b"Q".to_vec())
    }
    /// `/MaxLen` (Maximum text field length)
    pub fn max_len() -> Self {
        Self::from_bytes(b"MaxLen".to_vec())
    }
    /// `/Btn` (Button field type)
    pub fn btn() -> Self {
        Self::from_bytes(b"Btn".to_vec())
    }
    /// `/Tx` (Text field type)
    pub fn tx() -> Self {
        Self::from_bytes(b"Tx".to_vec())
    }
    /// `/Ch` (Choice field type)
    pub fn ch() -> Self {
        Self::from_bytes(b"Ch".to_vec())
    }
    /// `/Sig` (Signature field type)
    pub fn sig() -> Self {
        Self::from_bytes(b"Sig".to_vec())
    }
    /// `/Ff` (Field flags)
    pub fn ff() -> Self {
        Self::from_bytes(b"Ff".to_vec())
    }
    /// `/AS` (Appearance state)
    pub fn as_name() -> Self {
        Self::from_bytes(b"AS".to_vec())
    }
    /// `/XFA` (XFA form data stream in AcroForm dictionary)
    pub fn xfa() -> Self {
        Self::from_bytes(b"XFA".to_vec())
    }
    /// `/NeedsRendering` (catalog entry: true if XFA foreground rendering required)
    pub fn needs_rendering() -> Self {
        Self::from_bytes(b"NeedsRendering".to_vec())
    }

    // --- Phase 6: Additional Actions ---

    /// `/JavaScript` (JavaScript action type)
    pub fn java_script() -> Self {
        Self::from_bytes(b"JavaScript".to_vec())
    }
    /// `/SubmitForm` (Submit form action)
    pub fn submit_form() -> Self {
        Self::from_bytes(b"SubmitForm".to_vec())
    }
    /// `/ResetForm` (Reset form action)
    pub fn reset_form() -> Self {
        Self::from_bytes(b"ResetForm".to_vec())
    }
    /// `/ImportData` (Import data action)
    pub fn import_data() -> Self {
        Self::from_bytes(b"ImportData".to_vec())
    }
    /// `/JS` (JavaScript code)
    pub fn js() -> Self {
        Self::from_bytes(b"JS".to_vec())
    }
    /// `/Sound` (Sound action)
    pub fn sound() -> Self {
        Self::from_bytes(b"Sound".to_vec())
    }
    /// `/Movie` (Movie action)
    pub fn movie() -> Self {
        Self::from_bytes(b"Movie".to_vec())
    }
    /// `/Rendition` (Rendition action)
    pub fn rendition() -> Self {
        Self::from_bytes(b"Rendition".to_vec())
    }

    // --- Phase 6: Linearization Hints ---

    /// `/H` (Hint stream entry)
    pub fn h() -> Self {
        Self::from_bytes(b"H".to_vec())
    }

    // --- Phase 6: Tagged PDF ---

    /// `/StructTreeRoot`
    pub fn struct_tree_root() -> Self {
        Self::from_bytes(b"StructTreeRoot".to_vec())
    }
    /// `/Alt` (Alternative text)
    pub fn alt() -> Self {
        Self::from_bytes(b"Alt".to_vec())
    }
    /// `/MCID` (Marked content identifier)
    pub fn mcid() -> Self {
        Self::from_bytes(b"MCID".to_vec())
    }
    /// `/Pg` (Page reference for structure element)
    pub fn pg() -> Self {
        Self::from_bytes(b"Pg".to_vec())
    }
    /// `/RoleMap` (Custom tag to standard tag mapping)
    pub fn role_map() -> Self {
        Self::from_bytes(b"RoleMap".to_vec())
    }
    /// `/ParentTree` (Number tree for parent structure elements)
    pub fn parent_tree() -> Self {
        Self::from_bytes(b"ParentTree".to_vec())
    }
    /// `/Lang` (Language tag)
    pub fn lang() -> Self {
        Self::from_bytes(b"Lang".to_vec())
    }
    /// `/ObjType` (Structure element object type: "Elem", "MCR", "OBJR")
    pub fn obj_type() -> Self {
        Self::from_bytes(b"ObjType".to_vec())
    }

    // --- Phase 6: TrueType Charset ---

    /// `/MacRomanEncoding`
    pub fn mac_roman_encoding() -> Self {
        Self::from_bytes(b"MacRomanEncoding".to_vec())
    }
    /// `/MacExpertEncoding`
    pub fn mac_expert_encoding() -> Self {
        Self::from_bytes(b"MacExpertEncoding".to_vec())
    }
    /// `/WinAnsiEncoding`
    pub fn win_ansi_encoding() -> Self {
        Self::from_bytes(b"WinAnsiEncoding".to_vec())
    }
    /// `/Flags` (Font descriptor flags)
    pub fn flags() -> Self {
        Self::from_bytes(b"Flags".to_vec())
    }

    // --- Additional Actions / Viewer Preferences / Overprint ---

    /// `/AA` (Additional actions)
    pub fn aa() -> Self {
        Self::from_bytes(b"AA".to_vec())
    }
    /// `/CO` (Calculation order)
    pub fn co() -> Self {
        Self::from_bytes(b"CO".to_vec())
    }
    /// `/ViewerPreferences`
    pub fn viewer_preferences() -> Self {
        Self::from_bytes(b"ViewerPreferences".to_vec())
    }
    /// `/OP` (Overprint for fill)
    pub fn op_upper() -> Self {
        Self::from_bytes(b"OP".to_vec())
    }
    /// `/op` (Overprint for stroke)
    pub fn op_lower() -> Self {
        Self::from_bytes(b"op".to_vec())
    }
    /// `/OPM` (Overprint mode)
    pub fn opm() -> Self {
        Self::from_bytes(b"OPM".to_vec())
    }
    /// `/Matte` (Matte color for soft mask)
    pub fn matte() -> Self {
        Self::from_bytes(b"Matte".to_vec())
    }
    /// `/HideToolbar`
    pub fn hide_toolbar() -> Self {
        Self::from_bytes(b"HideToolbar".to_vec())
    }
    /// `/HideMenubar`
    pub fn hide_menubar() -> Self {
        Self::from_bytes(b"HideMenubar".to_vec())
    }
    /// `/HideWindowUI`
    pub fn hide_window_ui() -> Self {
        Self::from_bytes(b"HideWindowUI".to_vec())
    }
    /// `/FitWindow`
    pub fn fit_window() -> Self {
        Self::from_bytes(b"FitWindow".to_vec())
    }
    /// `/CenterWindow`
    pub fn center_window() -> Self {
        Self::from_bytes(b"CenterWindow".to_vec())
    }
    /// `/DisplayDocTitle`
    pub fn display_doc_title() -> Self {
        Self::from_bytes(b"DisplayDocTitle".to_vec())
    }
    /// `/Direction`
    pub fn direction() -> Self {
        Self::from_bytes(b"Direction".to_vec())
    }
    /// `/PrintScaling`
    pub fn print_scaling() -> Self {
        Self::from_bytes(b"PrintScaling".to_vec())
    }
    /// `/NumCopies`
    pub fn num_copies() -> Self {
        Self::from_bytes(b"NumCopies".to_vec())
    }
    /// `/Duplex`
    pub fn duplex() -> Self {
        Self::from_bytes(b"Duplex".to_vec())
    }
    /// `/BPC` (BitsPerComponent abbreviation)
    pub fn bpc() -> Self {
        Self::from_bytes(b"BPC".to_vec())
    }

    // --- P3 Gap Fix: MK Dictionary / Actions / FileSpec ---

    /// `/MK` (Widget appearance characteristics)
    pub fn mk() -> Self {
        Self::from_bytes(b"MK".to_vec())
    }
    /// `/BG` (Background color in MK dict)
    pub fn bg_color() -> Self {
        Self::from_bytes(b"BG".to_vec())
    }
    /// `/CA` (Caption in MK dict / normal caption)
    pub fn ca_display() -> Self {
        Self::from_bytes(b"CA".to_vec())
    }
    /// `/TP` (Text position in MK dict)
    pub fn tp() -> Self {
        Self::from_bytes(b"TP".to_vec())
    }
    /// `/GoToE` (Embedded GoTo action)
    pub fn go_to_e() -> Self {
        Self::from_bytes(b"GoToE".to_vec())
    }
    /// `/SetOCGState` (Set optional content group state action)
    pub fn set_ocg_state() -> Self {
        Self::from_bytes(b"SetOCGState".to_vec())
    }
    /// `/Trans` (Transition action)
    pub fn trans_action() -> Self {
        Self::from_bytes(b"Trans".to_vec())
    }
    /// `/GoTo3DView` (Go to 3D view action)
    pub fn go_to_3d_view() -> Self {
        Self::from_bytes(b"GoTo3DView".to_vec())
    }
    /// `/Hide` (Hide action)
    pub fn hide() -> Self {
        Self::from_bytes(b"Hide".to_vec())
    }
    /// `/Thread` (Thread action)
    pub fn thread() -> Self {
        Self::from_bytes(b"Thread".to_vec())
    }
    /// `/EF` (Embedded file dict in FileSpec)
    pub fn ef() -> Self {
        Self::from_bytes(b"EF".to_vec())
    }
    /// `/UF` (Unicode filename in FileSpec)
    pub fn uf() -> Self {
        Self::from_bytes(b"UF".to_vec())
    }
    /// `/DOS` (DOS filename in FileSpec)
    pub fn dos() -> Self {
        Self::from_bytes(b"DOS".to_vec())
    }
    /// `/Filespec` (FileSpec type name)
    pub fn file_spec_type() -> Self {
        Self::from_bytes(b"Filespec".to_vec())
    }
    /// `/Unix` (Unix filename in FileSpec)
    pub fn unix_name() -> Self {
        Self::from_bytes(b"Unix".to_vec())
    }
    /// `/FS` (File system name in FileSpec)
    pub fn fs() -> Self {
        Self::from_bytes(b"FS".to_vec())
    }
    /// `/Desc` (Description in FileSpec)
    pub fn desc() -> Self {
        Self::from_bytes(b"Desc".to_vec())
    }
    /// `/State` (OCG state array)
    pub fn state() -> Self {
        Self::from_bytes(b"State".to_vec())
    }
    /// `/AC` (Alternate caption in MK dict)
    pub fn ac() -> Self {
        Self::from_bytes(b"AC".to_vec())
    }
    /// `/RI` (Rollover icon in MK dict)
    pub fn ri() -> Self {
        Self::from_bytes(b"RI".to_vec())
    }
    /// `/IX` (Alternate icon in MK dict)
    pub fn ix() -> Self {
        Self::from_bytes(b"IX".to_vec())
    }
    /// `/IF` (Icon fit dictionary in MK dict)
    pub fn if_dict() -> Self {
        Self::from_bytes(b"IF".to_vec())
    }
    /// `/SW` (Scale method in IconFit: A/B/S/N)
    pub fn sw() -> Self {
        Self::from_bytes(b"SW".to_vec())
    }
    /// `/FB` (Fitting bounds flag in IconFit)
    pub fn fb() -> Self {
        Self::from_bytes(b"FB".to_vec())
    }

    // --- fpdfdoc audit fix: missing Name constants ---

    /// `/PrintPageRange` (Viewer preferences: page range array)
    pub fn print_page_range() -> Self {
        Self::from_bytes(b"PrintPageRange".to_vec())
    }
    /// `/TM` (Mapping name for form field export)
    pub fn tm() -> Self {
        Self::from_bytes(b"TM".to_vec())
    }
    /// `/NewWindow` (GoToR/GoToE: open in new window flag)
    pub fn new_window() -> Self {
        Self::from_bytes(b"NewWindow".to_vec())
    }

    // --- Missing constants (audit G1-G8) ---

    /// `/M` (annotation modification date)
    pub fn m() -> Self {
        Self::from_bytes(b"M".to_vec())
    }
    /// `/StructParent` (tagged PDF structure parent key)
    pub fn struct_parent() -> Self {
        Self::from_bytes(b"StructParent".to_vec())
    }
    /// `/DL` (decompressed stream length hint)
    pub fn dl() -> Self {
        Self::from_bytes(b"DL".to_vec())
    }
    /// `/DS` (rich text default style string)
    pub fn ds() -> Self {
        Self::from_bytes(b"DS".to_vec())
    }
    /// `/RV` (rich text value)
    pub fn rv() -> Self {
        Self::from_bytes(b"RV".to_vec())
    }
    /// `/PDFDocEncoding` (font encoding name)
    pub fn pdf_doc_encoding() -> Self {
        Self::from_bytes(b"PDFDocEncoding".to_vec())
    }
    /// `/Alpha` (soft-mask subtype value)
    pub fn alpha() -> Self {
        Self::from_bytes(b"Alpha".to_vec())
    }
    /// `/Transparency` (transparency group subtype value)
    pub fn transparency() -> Self {
        Self::from_bytes(b"Transparency".to_vec())
    }

    // --- Digital Signatures (fpdf_signature) ---

    /// `/ByteRange` (signature byte range array)
    pub fn byte_range() -> Self {
        Self::from_bytes(b"ByteRange".to_vec())
    }
    /// `/SubFilter` (signature sub-filter name)
    pub fn sub_filter() -> Self {
        Self::from_bytes(b"SubFilter".to_vec())
    }
    /// `/Reason` (signature reason string)
    pub fn reason() -> Self {
        Self::from_bytes(b"Reason".to_vec())
    }
    /// `/Reference` (signature reference array)
    pub fn reference() -> Self {
        Self::from_bytes(b"Reference".to_vec())
    }
    /// `/TransformMethod` (signature transform method name)
    pub fn transform_method() -> Self {
        Self::from_bytes(b"TransformMethod".to_vec())
    }
    /// `/TransformParams` (signature transform parameters dict)
    pub fn transform_params() -> Self {
        Self::from_bytes(b"TransformParams".to_vec())
    }
    /// `/DocMDP` (DocMDP transform method name)
    pub fn doc_mdp() -> Self {
        Self::from_bytes(b"DocMDP".to_vec())
    }

    // --- FontEncoding / Thumbnail ---

    /// `/Differences` (encoding differences array)
    pub fn differences() -> Self {
        Self::from_bytes(b"Differences".to_vec())
    }
    /// `/Thumb` (page thumbnail image)
    pub fn thumb() -> Self {
        Self::from_bytes(b"Thumb".to_vec())
    }

    // --- Tagged PDF / Page Mode (FPDFCatalog_IsTagged / FPDFDoc_GetPageMode) ---

    /// `/MarkInfo` (tagged PDF mark information dict in catalog)
    pub fn mark_info() -> Self {
        Self::from_bytes(b"MarkInfo".to_vec())
    }
    /// `/Marked` (boolean in MarkInfo dict: true = tagged PDF)
    pub fn marked() -> Self {
        Self::from_bytes(b"Marked".to_vec())
    }
    /// `/PageMode` (catalog entry controlling initial view: UseNone, UseOutlines, etc.)
    pub fn page_mode() -> Self {
        Self::from_bytes(b"PageMode".to_vec())
    }

    // --- Attachment/EmbeddedFile ---

    /// `/Params` (embedded file parameter dict in EF stream)
    pub fn params() -> Self {
        Self::from_bytes(b"Params".to_vec())
    }
    /// `/CheckSum` (MD5 checksum in Params dict)
    pub fn check_sum() -> Self {
        Self::from_bytes(b"CheckSum".to_vec())
    }

    // --- Annotation reply / in-reply-to ---

    /// `/IRT` (In Reply To — annotation that this annotation is a reply to)
    pub fn irt() -> Self {
        Self::from_bytes(b"IRT".to_vec())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_name_from_bytes() {
        let name = Name::from_bytes(b"Type".to_vec());
        assert_eq!(name.as_bytes(), b"Type");
    }

    #[test]
    fn test_name_from_str() {
        let name = Name::from("Filter");
        assert_eq!(name.as_bytes(), b"Filter");
    }

    #[test]
    fn test_name_as_str() {
        let name = Name::from_bytes(b"Length".to_vec());
        assert_eq!(name.as_str().as_ref(), "Length");
    }

    #[test]
    fn test_name_display() {
        let name = Name::from_bytes(b"Type".to_vec());
        assert_eq!(format!("{name}"), "/Type");
    }

    #[test]
    fn test_name_debug() {
        let name = Name::from_bytes(b"Type".to_vec());
        assert_eq!(format!("{name:?}"), "Name(/Type)");
    }

    #[test]
    fn test_name_equality() {
        let a = Name::from_bytes(b"Type".to_vec());
        let b = Name::from_bytes(b"Type".to_vec());
        let c = Name::from_bytes(b"Subtype".to_vec());
        assert_eq!(a, b);
        assert_ne!(a, c);
    }

    #[test]
    fn test_name_ordering() {
        let a = Name::from_bytes(b"A".to_vec());
        let b = Name::from_bytes(b"B".to_vec());
        assert!(a < b);
    }

    #[test]
    fn test_name_hash() {
        use std::collections::HashMap;
        let mut map = HashMap::new();
        map.insert(Name::from("Type"), "Catalog");
        assert_eq!(map.get(&Name::from("Type")), Some(&"Catalog"));
    }

    #[test]
    fn test_predefined_type() {
        let name = Name::r#type();
        assert_eq!(name.as_bytes(), b"Type");
    }

    #[test]
    fn test_predefined_length() {
        let name = Name::length();
        assert_eq!(name.as_bytes(), b"Length");
    }

    #[test]
    fn test_predefined_filter() {
        let name = Name::filter();
        assert_eq!(name.as_bytes(), b"Filter");
    }

    #[test]
    fn test_predefined_flate_decode() {
        let name = Name::flate_decode();
        assert_eq!(name.as_bytes(), b"FlateDecode");
    }

    #[test]
    fn test_predefined_names_equal_constructed() {
        assert_eq!(Name::r#type(), Name::from("Type"));
        assert_eq!(Name::length(), Name::from("Length"));
        assert_eq!(Name::filter(), Name::from("Filter"));
        assert_eq!(Name::pages(), Name::from("Pages"));
        assert_eq!(Name::media_box(), Name::from("MediaBox"));
        assert_eq!(Name::root(), Name::from("Root"));
        assert_eq!(Name::catalog(), Name::from("Catalog"));
    }

    #[test]
    fn test_name_with_non_ascii_bytes() {
        let name = Name::from_bytes(vec![0x80, 0x81, 0x82]);
        // as_str should produce lossy UTF-8
        let s = name.as_str();
        assert!(!s.is_empty());
    }

    #[test]
    fn test_name_is_send_sync() {
        fn assert_send_sync<T: Send + Sync>() {}
        assert_send_sync::<Name>();
    }

    #[test]
    fn test_name_clone() {
        let a = Name::from("Test");
        let b = a.clone();
        assert_eq!(a, b);
    }

    #[test]
    fn test_name_constants_match_expected_strings() {
        assert_eq!(Name::r#type().as_str().as_ref(), "Type");
        assert_eq!(Name::page().as_str().as_ref(), "Page");
        assert_eq!(Name::rotate().as_str().as_ref(), "Rotate");
        assert_eq!(Name::resources().as_str().as_ref(), "Resources");
        assert_eq!(Name::font().as_str().as_ref(), "Font");
        assert_eq!(Name::media_box().as_str().as_ref(), "MediaBox");
        assert_eq!(Name::contents().as_str().as_ref(), "Contents");
        assert_eq!(Name::annots().as_str().as_ref(), "Annots");
        assert_eq!(Name::subtype().as_str().as_ref(), "Subtype");
        assert_eq!(Name::filter().as_str().as_ref(), "Filter");
        assert_eq!(Name::flate_decode().as_str().as_ref(), "FlateDecode");
        assert_eq!(Name::acro_form().as_str().as_ref(), "AcroForm");
    }
}
