libperl_rs/cop.rs
1//! `Cop` newtype — a non-null handle to a Perl `COP` ("control op":
2//! the `nextstate` / `dbstate` statement-boundary ops that carry
3//! source location). This is the source↔OP mapping piece of Step 2 —
4//! `CopFILE` / `CopLINE` extraction per `docs/plan/README.md` §4
5//! Step 3.3, promoted into the newtype layer.
6//!
7//! Obtain one via [`Op::as_cop`](crate::Op::as_cop) (class-checked) or
8//! [`Cv::first_cop`](crate::Cv::first_cop).
9
10use std::ptr::NonNull;
11
12use libperl_sys::COP;
13
14/// Non-null pointer to a Perl `COP`. Same ABI as `*mut COP`.
15/// Non-owning, like the other newtypes.
16#[derive(Clone, Copy)]
17#[repr(transparent)]
18pub struct Cop(NonNull<COP>);
19
20impl Cop {
21 /// Wrap a raw COP pointer without checking for null.
22 ///
23 /// # Safety
24 /// Caller must guarantee `p` is non-null and points to a valid
25 /// COP for at least the lifetime of the resulting `Cop`. Prefer
26 /// [`Op::as_cop`](crate::Op::as_cop), which class-checks first.
27 #[inline]
28 pub unsafe fn from_raw_unchecked(p: *const COP) -> Self {
29 debug_assert!(!p.is_null(), "Cop::from_raw_unchecked received a null pointer");
30 Cop(unsafe { NonNull::new_unchecked(p as *mut COP) })
31 }
32
33 /// Wrap a raw COP pointer, returning `None` on null input.
34 #[inline]
35 pub fn from_raw(p: *const COP) -> Option<Self> {
36 NonNull::new(p as *mut COP).map(Cop)
37 }
38
39 /// Raw pointer for FFI calls.
40 #[inline]
41 pub fn as_ptr(&self) -> *mut COP {
42 self.0.as_ptr()
43 }
44
45 /// Source line of the statement this COP opens (`CopLINE`).
46 #[inline]
47 pub fn line(&self) -> u32 {
48 unsafe { libperl_sys::CopLINE(self.0.as_ptr()) }
49 }
50
51 /// Source file of the statement (`CopFILE`); `"-e"` for one-liner
52 /// scripts, `"(eval N)"` inside string evals.
53 pub fn file(&self) -> Option<String> {
54 let p = unsafe { libperl_sys::CopFILE(self.0.as_ptr()) };
55 if p.is_null() {
56 None
57 } else {
58 Some(
59 unsafe { std::ffi::CStr::from_ptr(p) }
60 .to_string_lossy()
61 .into_owned(),
62 )
63 }
64 }
65}