Vendor dependencies

This commit is contained in:
2026-08-01 16:11:49 +03:00
parent 7f139a0241
commit 6b5e7f0f8b
29706 changed files with 9575646 additions and 0 deletions
+127
View File
@@ -0,0 +1,127 @@
use std::fmt::{self, Debug, Display, Write as _};
use std::marker::PhantomData;
use std::ptr::NonNull;
use std::slice;
use std::str;
#[derive(Copy, Clone)]
pub(crate) struct CStr<'a> {
ptr: NonNull<u8>,
marker: PhantomData<&'a [u8]>,
}
unsafe impl<'a> Send for CStr<'a> {}
unsafe impl<'a> Sync for CStr<'a> {}
impl<'a> CStr<'a> {
pub fn from_bytes_with_nul(bytes: &'static [u8]) -> Self {
assert_eq!(bytes.last(), Some(&b'\0'));
let ptr = NonNull::from(bytes).cast();
unsafe { Self::from_ptr(ptr) }
}
pub unsafe fn from_ptr(ptr: NonNull<i8>) -> Self {
CStr {
ptr: ptr.cast(),
marker: PhantomData,
}
}
pub fn len(self) -> usize {
let start = self.ptr.as_ptr();
let mut end = start;
unsafe {
while *end != 0 {
end = end.add(1);
}
end.offset_from(start) as usize
}
}
pub fn to_bytes(self) -> &'a [u8] {
let len = self.len();
unsafe { slice::from_raw_parts(self.ptr.as_ptr(), len) }
}
}
impl<'a> Display for CStr<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let ptr = self.ptr.as_ptr();
let len = self.len();
let bytes = unsafe { slice::from_raw_parts(ptr, len) };
display_lossy(bytes, formatter)
}
}
impl<'a> Debug for CStr<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let ptr = self.ptr.as_ptr();
let len = self.len();
let bytes = unsafe { slice::from_raw_parts(ptr, len) };
debug_lossy(bytes, formatter)
}
}
fn display_lossy(mut bytes: &[u8], formatter: &mut fmt::Formatter) -> fmt::Result {
loop {
match str::from_utf8(bytes) {
Ok(valid) => return formatter.write_str(valid),
Err(utf8_error) => {
let valid_up_to = utf8_error.valid_up_to();
let valid = unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) };
formatter.write_str(valid)?;
formatter.write_char(char::REPLACEMENT_CHARACTER)?;
if let Some(error_len) = utf8_error.error_len() {
bytes = &bytes[valid_up_to + error_len..];
} else {
return Ok(());
}
}
}
}
}
pub(crate) fn debug_lossy(mut bytes: &[u8], formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_char('"')?;
while !bytes.is_empty() {
let from_utf8_result = str::from_utf8(bytes);
let valid = match from_utf8_result {
Ok(valid) => valid,
Err(utf8_error) => {
let valid_up_to = utf8_error.valid_up_to();
unsafe { str::from_utf8_unchecked(&bytes[..valid_up_to]) }
}
};
let mut written = 0;
for (i, ch) in valid.char_indices() {
let esc = ch.escape_debug();
if esc.len() != 1 && ch != '\'' {
formatter.write_str(&valid[written..i])?;
for ch in esc {
formatter.write_char(ch)?;
}
written = i + ch.len_utf8();
}
}
formatter.write_str(&valid[written..])?;
match from_utf8_result {
Ok(_valid) => break,
Err(utf8_error) => {
let end_of_broken = if let Some(error_len) = utf8_error.error_len() {
valid.len() + error_len
} else {
bytes.len()
};
for b in &bytes[valid.len()..end_of_broken] {
write!(formatter, "\\x{:02x}", b)?;
}
bytes = &bytes[end_of_broken..];
}
}
}
formatter.write_char('"')
}
@@ -0,0 +1,217 @@
use crate::libyaml;
use crate::libyaml::util::Owned;
use std::ffi::c_void;
use std::io;
use std::mem::{self, MaybeUninit};
use std::ptr::{self, addr_of_mut};
use std::slice;
use unsafe_libyaml as sys;
#[derive(Debug)]
pub(crate) enum Error {
Libyaml(libyaml::error::Error),
Io(io::Error),
}
pub(crate) struct Emitter<'a> {
pin: Owned<EmitterPinned<'a>>,
}
struct EmitterPinned<'a> {
sys: sys::yaml_emitter_t,
write: Box<dyn io::Write + 'a>,
write_error: Option<io::Error>,
}
#[derive(Debug)]
pub(crate) enum Event<'a> {
StreamStart,
StreamEnd,
DocumentStart,
DocumentEnd,
Scalar(Scalar<'a>),
SequenceStart(Sequence),
SequenceEnd,
MappingStart(Mapping),
MappingEnd,
}
#[derive(Debug)]
pub(crate) struct Scalar<'a> {
pub tag: Option<String>,
pub value: &'a str,
pub style: ScalarStyle,
}
#[derive(Debug)]
pub(crate) enum ScalarStyle {
Any,
Plain,
SingleQuoted,
Literal,
}
#[derive(Debug)]
pub(crate) struct Sequence {
pub tag: Option<String>,
}
#[derive(Debug)]
pub(crate) struct Mapping {
pub tag: Option<String>,
}
impl<'a> Emitter<'a> {
pub fn new(write: Box<dyn io::Write + 'a>) -> Emitter<'a> {
let owned = Owned::<EmitterPinned>::new_uninit();
let pin = unsafe {
let emitter = addr_of_mut!((*owned.ptr).sys);
if sys::yaml_emitter_initialize(emitter).fail {
panic!("malloc error: {}", libyaml::Error::emit_error(emitter));
}
sys::yaml_emitter_set_unicode(emitter, true);
sys::yaml_emitter_set_width(emitter, -1);
addr_of_mut!((*owned.ptr).write).write(write);
addr_of_mut!((*owned.ptr).write_error).write(None);
sys::yaml_emitter_set_output(emitter, write_handler, owned.ptr.cast());
Owned::assume_init(owned)
};
Emitter { pin }
}
pub fn emit(&mut self, event: Event) -> Result<(), Error> {
let mut sys_event = MaybeUninit::<sys::yaml_event_t>::uninit();
let sys_event = sys_event.as_mut_ptr();
unsafe {
let emitter = addr_of_mut!((*self.pin.ptr).sys);
let initialize_status = match event {
Event::StreamStart => {
sys::yaml_stream_start_event_initialize(sys_event, sys::YAML_UTF8_ENCODING)
}
Event::StreamEnd => sys::yaml_stream_end_event_initialize(sys_event),
Event::DocumentStart => {
let version_directive = ptr::null_mut();
let tag_directives_start = ptr::null_mut();
let tag_directives_end = ptr::null_mut();
let implicit = true;
sys::yaml_document_start_event_initialize(
sys_event,
version_directive,
tag_directives_start,
tag_directives_end,
implicit,
)
}
Event::DocumentEnd => {
let implicit = true;
sys::yaml_document_end_event_initialize(sys_event, implicit)
}
Event::Scalar(mut scalar) => {
let anchor = ptr::null();
let tag = scalar.tag.as_mut().map_or_else(ptr::null, |tag| {
tag.push('\0');
tag.as_ptr()
});
let value = scalar.value.as_ptr();
let length = scalar.value.len() as i32;
let plain_implicit = tag.is_null();
let quoted_implicit = tag.is_null();
let style = match scalar.style {
ScalarStyle::Any => sys::YAML_ANY_SCALAR_STYLE,
ScalarStyle::Plain => sys::YAML_PLAIN_SCALAR_STYLE,
ScalarStyle::SingleQuoted => sys::YAML_SINGLE_QUOTED_SCALAR_STYLE,
ScalarStyle::Literal => sys::YAML_LITERAL_SCALAR_STYLE,
};
sys::yaml_scalar_event_initialize(
sys_event,
anchor,
tag,
value,
length,
plain_implicit,
quoted_implicit,
style,
)
}
Event::SequenceStart(mut sequence) => {
let anchor = ptr::null();
let tag = sequence.tag.as_mut().map_or_else(ptr::null, |tag| {
tag.push('\0');
tag.as_ptr()
});
let implicit = tag.is_null();
let style = sys::YAML_ANY_SEQUENCE_STYLE;
sys::yaml_sequence_start_event_initialize(
sys_event, anchor, tag, implicit, style,
)
}
Event::SequenceEnd => sys::yaml_sequence_end_event_initialize(sys_event),
Event::MappingStart(mut mapping) => {
let anchor = ptr::null();
let tag = mapping.tag.as_mut().map_or_else(ptr::null, |tag| {
tag.push('\0');
tag.as_ptr()
});
let implicit = tag.is_null();
let style = sys::YAML_ANY_MAPPING_STYLE;
sys::yaml_mapping_start_event_initialize(
sys_event, anchor, tag, implicit, style,
)
}
Event::MappingEnd => sys::yaml_mapping_end_event_initialize(sys_event),
};
if initialize_status.fail {
return Err(Error::Libyaml(libyaml::Error::emit_error(emitter)));
}
if sys::yaml_emitter_emit(emitter, sys_event).fail {
return Err(self.error());
}
}
Ok(())
}
pub fn flush(&mut self) -> Result<(), Error> {
unsafe {
let emitter = addr_of_mut!((*self.pin.ptr).sys);
if sys::yaml_emitter_flush(emitter).fail {
return Err(self.error());
}
}
Ok(())
}
pub fn into_inner(self) -> Box<dyn io::Write + 'a> {
let sink = Box::new(io::sink());
unsafe { mem::replace(&mut (*self.pin.ptr).write, sink) }
}
fn error(&mut self) -> Error {
let emitter = unsafe { &mut *self.pin.ptr };
if let Some(write_error) = emitter.write_error.take() {
Error::Io(write_error)
} else {
Error::Libyaml(unsafe { libyaml::Error::emit_error(&emitter.sys) })
}
}
}
unsafe fn write_handler(data: *mut c_void, buffer: *mut u8, size: u64) -> i32 {
let data = data.cast::<EmitterPinned>();
match io::Write::write_all(unsafe { &mut *(*data).write }, unsafe {
slice::from_raw_parts(buffer, size as usize)
}) {
Ok(()) => 1,
Err(err) => {
unsafe {
(*data).write_error = Some(err);
}
0
}
}
}
impl<'a> Drop for EmitterPinned<'a> {
fn drop(&mut self) {
unsafe { sys::yaml_emitter_delete(&mut self.sys) }
}
}
+162
View File
@@ -0,0 +1,162 @@
use crate::libyaml::cstr::CStr;
use std::fmt::{self, Debug, Display};
use std::mem::MaybeUninit;
use std::ptr::NonNull;
use unsafe_libyaml as sys;
pub(crate) type Result<T> = std::result::Result<T, Error>;
pub(crate) struct Error {
kind: sys::yaml_error_type_t,
problem: CStr<'static>,
problem_offset: u64,
problem_mark: Mark,
context: Option<CStr<'static>>,
context_mark: Mark,
}
impl Error {
pub unsafe fn parse_error(parser: *const sys::yaml_parser_t) -> Self {
Error {
kind: unsafe { (*parser).error },
problem: match NonNull::new(unsafe { (*parser).problem as *mut _ }) {
Some(problem) => unsafe { CStr::from_ptr(problem) },
None => CStr::from_bytes_with_nul(b"libyaml parser failed but there is no error\0"),
},
problem_offset: unsafe { (*parser).problem_offset },
problem_mark: Mark {
sys: unsafe { (*parser).problem_mark },
},
context: match NonNull::new(unsafe { (*parser).context as *mut _ }) {
Some(context) => Some(unsafe { CStr::from_ptr(context) }),
None => None,
},
context_mark: Mark {
sys: unsafe { (*parser).context_mark },
},
}
}
pub unsafe fn emit_error(emitter: *const sys::yaml_emitter_t) -> Self {
Error {
kind: unsafe { (*emitter).error },
problem: match NonNull::new(unsafe { (*emitter).problem as *mut _ }) {
Some(problem) => unsafe { CStr::from_ptr(problem) },
None => {
CStr::from_bytes_with_nul(b"libyaml emitter failed but there is no error\0")
}
},
problem_offset: 0,
problem_mark: Mark {
sys: unsafe { MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init() },
},
context: None,
context_mark: Mark {
sys: unsafe { MaybeUninit::<sys::yaml_mark_t>::zeroed().assume_init() },
},
}
}
pub fn mark(&self) -> Mark {
self.problem_mark
}
}
impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{}", self.problem)?;
if self.problem_mark.sys.line != 0 || self.problem_mark.sys.column != 0 {
write!(formatter, " at {}", self.problem_mark)?;
} else if self.problem_offset != 0 {
write!(formatter, " at position {}", self.problem_offset)?;
}
if let Some(context) = &self.context {
write!(formatter, ", {}", context)?;
if (self.context_mark.sys.line != 0 || self.context_mark.sys.column != 0)
&& (self.context_mark.sys.line != self.problem_mark.sys.line
|| self.context_mark.sys.column != self.problem_mark.sys.column)
{
write!(formatter, " at {}", self.context_mark)?;
}
}
Ok(())
}
}
impl Debug for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut formatter = formatter.debug_struct("Error");
if let Some(kind) = match self.kind {
sys::YAML_MEMORY_ERROR => Some("MEMORY"),
sys::YAML_READER_ERROR => Some("READER"),
sys::YAML_SCANNER_ERROR => Some("SCANNER"),
sys::YAML_PARSER_ERROR => Some("PARSER"),
sys::YAML_COMPOSER_ERROR => Some("COMPOSER"),
sys::YAML_WRITER_ERROR => Some("WRITER"),
sys::YAML_EMITTER_ERROR => Some("EMITTER"),
_ => None,
} {
formatter.field("kind", &format_args!("{}", kind));
}
formatter.field("problem", &self.problem);
if self.problem_mark.sys.line != 0 || self.problem_mark.sys.column != 0 {
formatter.field("problem_mark", &self.problem_mark);
} else if self.problem_offset != 0 {
formatter.field("problem_offset", &self.problem_offset);
}
if let Some(context) = &self.context {
formatter.field("context", context);
if self.context_mark.sys.line != 0 || self.context_mark.sys.column != 0 {
formatter.field("context_mark", &self.context_mark);
}
}
formatter.finish()
}
}
#[derive(Copy, Clone)]
pub(crate) struct Mark {
pub(super) sys: sys::yaml_mark_t,
}
impl Mark {
pub fn index(&self) -> u64 {
self.sys.index
}
pub fn line(&self) -> u64 {
self.sys.line
}
pub fn column(&self) -> u64 {
self.sys.column
}
}
impl Display for Mark {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.sys.line != 0 || self.sys.column != 0 {
write!(
formatter,
"line {} column {}",
self.sys.line + 1,
self.sys.column + 1,
)
} else {
write!(formatter, "position {}", self.sys.index)
}
}
}
impl Debug for Mark {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut formatter = formatter.debug_struct("Mark");
if self.sys.line != 0 || self.sys.column != 0 {
formatter.field("line", &(self.sys.line + 1));
formatter.field("column", &(self.sys.column + 1));
} else {
formatter.field("index", &self.sys.index);
}
formatter.finish()
}
}
+8
View File
@@ -0,0 +1,8 @@
mod cstr;
pub mod emitter;
pub mod error;
pub mod parser;
pub mod tag;
mod util;
use self::error::Error;
+201
View File
@@ -0,0 +1,201 @@
use crate::libyaml::cstr::{self, CStr};
use crate::libyaml::error::{Error, Mark, Result};
use crate::libyaml::tag::Tag;
use crate::libyaml::util::Owned;
use std::borrow::Cow;
use std::fmt::{self, Debug};
use std::mem::MaybeUninit;
use std::ptr::{addr_of_mut, NonNull};
use std::slice;
use unsafe_libyaml as sys;
pub(crate) struct Parser<'input> {
pin: Owned<ParserPinned<'input>>,
}
struct ParserPinned<'input> {
sys: sys::yaml_parser_t,
input: Cow<'input, [u8]>,
}
#[derive(Debug)]
pub(crate) enum Event<'input> {
StreamStart,
StreamEnd,
DocumentStart,
DocumentEnd,
Alias(Anchor),
Scalar(Scalar<'input>),
SequenceStart(SequenceStart),
SequenceEnd,
MappingStart(MappingStart),
MappingEnd,
}
pub(crate) struct Scalar<'input> {
pub anchor: Option<Anchor>,
pub tag: Option<Tag>,
pub value: Box<[u8]>,
pub style: ScalarStyle,
pub repr: Option<&'input [u8]>,
}
#[derive(Debug)]
pub(crate) struct SequenceStart {
pub anchor: Option<Anchor>,
pub tag: Option<Tag>,
}
#[derive(Debug)]
pub(crate) struct MappingStart {
pub anchor: Option<Anchor>,
pub tag: Option<Tag>,
}
#[derive(Ord, PartialOrd, Eq, PartialEq)]
pub(crate) struct Anchor(Box<[u8]>);
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub(crate) enum ScalarStyle {
Plain,
SingleQuoted,
DoubleQuoted,
Literal,
Folded,
}
impl<'input> Parser<'input> {
pub fn new(input: Cow<'input, [u8]>) -> Parser<'input> {
let owned = Owned::<ParserPinned>::new_uninit();
let pin = unsafe {
let parser = addr_of_mut!((*owned.ptr).sys);
if sys::yaml_parser_initialize(parser).fail {
panic!("malloc error: {}", Error::parse_error(parser));
}
sys::yaml_parser_set_encoding(parser, sys::YAML_UTF8_ENCODING);
sys::yaml_parser_set_input_string(parser, input.as_ptr(), input.len() as u64);
addr_of_mut!((*owned.ptr).input).write(input);
Owned::assume_init(owned)
};
Parser { pin }
}
pub fn next(&mut self) -> Result<(Event<'input>, Mark)> {
let mut event = MaybeUninit::<sys::yaml_event_t>::uninit();
unsafe {
let parser = addr_of_mut!((*self.pin.ptr).sys);
if (*parser).error != sys::YAML_NO_ERROR {
return Err(Error::parse_error(parser));
}
let event = event.as_mut_ptr();
if sys::yaml_parser_parse(parser, event).fail {
return Err(Error::parse_error(parser));
}
let ret = convert_event(&*event, &(*self.pin.ptr).input);
let mark = Mark {
sys: (*event).start_mark,
};
sys::yaml_event_delete(event);
Ok((ret, mark))
}
}
}
unsafe fn convert_event<'input>(
sys: &sys::yaml_event_t,
input: &Cow<'input, [u8]>,
) -> Event<'input> {
match sys.type_ {
sys::YAML_STREAM_START_EVENT => Event::StreamStart,
sys::YAML_STREAM_END_EVENT => Event::StreamEnd,
sys::YAML_DOCUMENT_START_EVENT => Event::DocumentStart,
sys::YAML_DOCUMENT_END_EVENT => Event::DocumentEnd,
sys::YAML_ALIAS_EVENT => {
Event::Alias(unsafe { optional_anchor(sys.data.alias.anchor) }.unwrap())
}
sys::YAML_SCALAR_EVENT => Event::Scalar(Scalar {
anchor: unsafe { optional_anchor(sys.data.scalar.anchor) },
tag: unsafe { optional_tag(sys.data.scalar.tag) },
value: Box::from(unsafe {
slice::from_raw_parts(sys.data.scalar.value, sys.data.scalar.length as usize)
}),
style: match unsafe { sys.data.scalar.style } {
sys::YAML_PLAIN_SCALAR_STYLE => ScalarStyle::Plain,
sys::YAML_SINGLE_QUOTED_SCALAR_STYLE => ScalarStyle::SingleQuoted,
sys::YAML_DOUBLE_QUOTED_SCALAR_STYLE => ScalarStyle::DoubleQuoted,
sys::YAML_LITERAL_SCALAR_STYLE => ScalarStyle::Literal,
sys::YAML_FOLDED_SCALAR_STYLE => ScalarStyle::Folded,
sys::YAML_ANY_SCALAR_STYLE | _ => unreachable!(),
},
repr: if let Cow::Borrowed(input) = input {
Some(&input[sys.start_mark.index as usize..sys.end_mark.index as usize])
} else {
None
},
}),
sys::YAML_SEQUENCE_START_EVENT => Event::SequenceStart(SequenceStart {
anchor: unsafe { optional_anchor(sys.data.sequence_start.anchor) },
tag: unsafe { optional_tag(sys.data.sequence_start.tag) },
}),
sys::YAML_SEQUENCE_END_EVENT => Event::SequenceEnd,
sys::YAML_MAPPING_START_EVENT => Event::MappingStart(MappingStart {
anchor: unsafe { optional_anchor(sys.data.mapping_start.anchor) },
tag: unsafe { optional_tag(sys.data.mapping_start.tag) },
}),
sys::YAML_MAPPING_END_EVENT => Event::MappingEnd,
sys::YAML_NO_EVENT => unreachable!(),
_ => unimplemented!(),
}
}
unsafe fn optional_anchor(anchor: *const u8) -> Option<Anchor> {
let ptr = NonNull::new(anchor as *mut i8)?;
let cstr = unsafe { CStr::from_ptr(ptr) };
Some(Anchor(Box::from(cstr.to_bytes())))
}
unsafe fn optional_tag(tag: *const u8) -> Option<Tag> {
let ptr = NonNull::new(tag as *mut i8)?;
let cstr = unsafe { CStr::from_ptr(ptr) };
Some(Tag(Box::from(cstr.to_bytes())))
}
impl<'input> Debug for Scalar<'input> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let Scalar {
anchor,
tag,
value,
style,
repr: _,
} = self;
struct LossySlice<'a>(&'a [u8]);
impl<'a> Debug for LossySlice<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
cstr::debug_lossy(self.0, formatter)
}
}
formatter
.debug_struct("Scalar")
.field("anchor", anchor)
.field("tag", tag)
.field("value", &LossySlice(value))
.field("style", style)
.finish()
}
}
impl Debug for Anchor {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
cstr::debug_lossy(&self.0, formatter)
}
}
impl<'input> Drop for ParserPinned<'input> {
fn drop(&mut self) {
unsafe { sys::yaml_parser_delete(&mut self.sys) }
}
}
+38
View File
@@ -0,0 +1,38 @@
use crate::libyaml::cstr;
use std::fmt::{self, Debug};
use std::ops::Deref;
#[derive(Ord, PartialOrd, Eq, PartialEq)]
pub(crate) struct Tag(pub(in crate::libyaml) Box<[u8]>);
impl Tag {
pub const NULL: &'static str = "tag:yaml.org,2002:null";
pub const BOOL: &'static str = "tag:yaml.org,2002:bool";
pub const INT: &'static str = "tag:yaml.org,2002:int";
pub const FLOAT: &'static str = "tag:yaml.org,2002:float";
}
impl Tag {
pub fn starts_with(&self, prefix: &str) -> bool {
self.0.starts_with(prefix.as_bytes())
}
}
impl PartialEq<str> for Tag {
fn eq(&self, other: &str) -> bool {
*self.0 == *other.as_bytes()
}
}
impl Deref for Tag {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Debug for Tag {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
cstr::debug_lossy(&self.0, formatter)
}
}
+48
View File
@@ -0,0 +1,48 @@
use std::marker::PhantomData;
use std::mem::{self, MaybeUninit};
use std::ops::Deref;
use std::ptr::{addr_of, NonNull};
pub(crate) struct Owned<T, Init = T> {
ptr: NonNull<T>,
marker: PhantomData<NonNull<Init>>,
}
impl<T> Owned<T> {
pub fn new_uninit() -> Owned<MaybeUninit<T>, T> {
// FIXME: use Box::new_uninit when stable
let boxed = Box::new(MaybeUninit::<T>::uninit());
Owned {
ptr: unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) },
marker: PhantomData,
}
}
pub unsafe fn assume_init(definitely_init: Owned<MaybeUninit<T>, T>) -> Owned<T> {
let ptr = definitely_init.ptr;
mem::forget(definitely_init);
Owned {
ptr: ptr.cast(),
marker: PhantomData,
}
}
}
#[repr(transparent)]
pub(crate) struct InitPtr<T> {
pub ptr: *mut T,
}
impl<T, Init> Deref for Owned<T, Init> {
type Target = InitPtr<Init>;
fn deref(&self) -> &Self::Target {
unsafe { &*addr_of!(self.ptr).cast::<InitPtr<Init>>() }
}
}
impl<T, Init> Drop for Owned<T, Init> {
fn drop(&mut self) {
let _ = unsafe { Box::from_raw(self.ptr.as_ptr()) };
}
}