Add utils for ptr->&str conversion

This commit is contained in:
FreezyLemon 2024-10-23 12:09:46 +02:00 committed by Josh Holmer
parent 814f8b9464
commit 251c09e732
24 changed files with 93 additions and 152 deletions

View File

@ -1,9 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use super::{Audio, Capabilities, Id, Profile, Video}; use super::{Audio, Capabilities, Id, Profile, Video};
use crate::ffi::*; use crate::ffi::*;
use crate::{media, Error}; use crate::{media, utils, Error};
#[derive(PartialEq, Eq, Copy, Clone)] #[derive(PartialEq, Eq, Copy, Clone)]
pub struct Codec { pub struct Codec {
@ -37,18 +34,11 @@ impl Codec {
} }
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
} }
pub fn description(&self) -> &str { pub fn description(&self) -> &str {
unsafe { unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
} }
pub fn medium(&self) -> media::Type { pub fn medium(&self) -> media::Type {

View File

@ -1,9 +1,7 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVCodecID::*; use crate::ffi::AVCodecID::*;
use crate::ffi::*; use crate::ffi::*;
use crate::util::media; use crate::util::media;
use crate::utils;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -661,7 +659,7 @@ impl Id {
} }
pub fn name(&self) -> &'static str { pub fn name(&self) -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avcodec_get_name((*self).into())).to_bytes()) } unsafe { utils::str_from_c_ptr(avcodec_get_name((*self).into())) }
} }
} }

View File

@ -48,19 +48,17 @@ pub mod decoder;
pub mod encoder; pub mod encoder;
pub mod traits; pub mod traits;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
pub fn version() -> u32 { pub fn version() -> u32 {
unsafe { avcodec_version() } unsafe { avcodec_version() }
} }
pub fn configuration() -> &'static str { pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avcodec_configuration()).to_bytes()) } unsafe { utils::str_from_c_ptr(avcodec_configuration()) }
} }
pub fn license() -> &'static str { pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avcodec_license()).to_bytes()) } unsafe { utils::str_from_c_ptr(avcodec_license()) }
} }

View File

@ -1,9 +1,8 @@
use std::ffi::CStr;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use super::{Flags, Type}; use super::{Flags, Type};
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[cfg(not(feature = "ffmpeg_5_0"))] #[cfg(not(feature = "ffmpeg_5_0"))]
use crate::{format, Picture}; use crate::{format, Picture};
@ -122,7 +121,7 @@ impl<'a> Text<'a> {
impl<'a> Text<'a> { impl<'a> Text<'a> {
pub fn get(&self) -> &str { pub fn get(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).text).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).text) }
} }
} }
@ -147,6 +146,6 @@ impl<'a> Ass<'a> {
impl<'a> Ass<'a> { impl<'a> Ass<'a> {
pub fn get(&self) -> &str { pub fn get(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).ass).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).ass) }
} }
} }

View File

@ -2,11 +2,10 @@ pub mod extensions;
pub mod input; pub mod input;
pub mod output; pub mod output;
use std::ffi::CStr;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
pub struct Info<'a> { pub struct Info<'a> {
ptr: *mut AVDeviceInfo, ptr: *mut AVDeviceInfo,
@ -33,13 +32,11 @@ impl<'a> Info<'a> {
impl<'a> Info<'a> { impl<'a> Info<'a> {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).device_name).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).device_name) }
} }
pub fn description(&self) -> &str { pub fn description(&self) -> &str {
unsafe { unsafe { utils::str_from_c_ptr((*self.as_ptr()).device_description) }
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).device_description).to_bytes())
}
} }
} }
@ -54,9 +51,9 @@ pub fn version() -> u32 {
} }
pub fn configuration() -> &'static str { pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avdevice_configuration()).to_bytes()) } unsafe { utils::str_from_c_ptr(avdevice_configuration()) }
} }
pub fn license() -> &'static str { pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avdevice_license()).to_bytes()) } unsafe { utils::str_from_c_ptr(avdevice_license()) }
} }

View File

@ -1,9 +1,8 @@
use std::ffi::CStr;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use super::{Flags, Pad}; use super::{Flags, Pad};
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
pub struct Filter { pub struct Filter {
ptr: *mut AVFilter, ptr: *mut AVFilter,
@ -25,19 +24,11 @@ impl Filter {
impl Filter { impl Filter {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
} }
pub fn description(&self) -> Option<&str> { pub fn description(&self) -> Option<&str> {
unsafe { unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).description) }
let ptr = (*self.as_ptr()).description;
if ptr.is_null() {
None
} else {
Some(from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
}
}
} }
pub fn inputs(&self) -> Option<PadIter> { pub fn inputs(&self) -> Option<PadIter> {

View File

@ -13,10 +13,10 @@ pub use self::context::{Context, Sink, Source};
pub mod graph; pub mod graph;
pub use self::graph::Graph; pub use self::graph::Graph;
use std::ffi::{CStr, CString}; use std::ffi::CString;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[cfg(not(feature = "ffmpeg_5_0"))] #[cfg(not(feature = "ffmpeg_5_0"))]
use crate::Error; use crate::Error;
@ -42,11 +42,11 @@ pub fn version() -> u32 {
} }
pub fn configuration() -> &'static str { pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avfilter_configuration()).to_bytes()) } unsafe { utils::str_from_c_ptr(avfilter_configuration()) }
} }
pub fn license() -> &'static str { pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avfilter_license()).to_bytes()) } unsafe { utils::str_from_c_ptr(avfilter_license()) }
} }
pub fn find(name: &str) -> Option<Filter> { pub fn find(name: &str) -> Option<Filter> {

View File

@ -1,9 +1,8 @@
use std::ffi::CStr;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::media; use crate::media;
use crate::utils;
pub struct Pad<'a> { pub struct Pad<'a> {
ptr: *const AVFilterPad, ptr: *const AVFilterPad,
@ -34,12 +33,7 @@ impl<'a> Pad<'a> {
pub fn name(&self) -> Option<&str> { pub fn name(&self) -> Option<&str> {
unsafe { unsafe {
let ptr = avfilter_pad_get_name(self.ptr, self.idx as i32); let ptr = avfilter_pad_get_name(self.ptr, self.idx as i32);
utils::optional_str_from_c_ptr(ptr)
if ptr.is_null() {
None
} else {
Some(from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
}
} }
} }

View File

@ -1,7 +1,5 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
pub struct Input { pub struct Input {
ptr: *mut AVInputFormat, ptr: *mut AVInputFormat,
@ -23,19 +21,11 @@ impl Input {
impl Input { impl Input {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
} }
pub fn description(&self) -> &str { pub fn description(&self) -> &str {
unsafe { unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
} }
pub fn extensions(&self) -> Vec<&str> { pub fn extensions(&self) -> Vec<&str> {
@ -45,9 +35,7 @@ impl Input {
if ptr.is_null() { if ptr.is_null() {
Vec::new() Vec::new()
} else { } else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()) utils::str_from_c_ptr(ptr).split(',').collect()
.split(',')
.collect()
} }
} }
} }
@ -59,9 +47,7 @@ impl Input {
if ptr.is_null() { if ptr.is_null() {
Vec::new() Vec::new()
} else { } else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()) utils::str_from_c_ptr(ptr).split(',').collect()
.split(',')
.collect()
} }
} }
} }

View File

@ -1,12 +1,11 @@
use std::path::Path; use std::path::Path;
use std::ffi::{CStr, CString}; use std::ffi::CString;
use std::ptr; use std::ptr;
use std::str::from_utf8_unchecked;
use super::Flags; use super::Flags;
use crate::ffi::*; use crate::ffi::*;
use crate::{codec, media}; use crate::{codec, media, utils};
pub struct Output { pub struct Output {
ptr: *mut AVOutputFormat, ptr: *mut AVOutputFormat,
@ -28,19 +27,11 @@ impl Output {
impl Output { impl Output {
pub fn name(&self) -> &str { pub fn name(&self) -> &str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
} }
pub fn description(&self) -> &str { pub fn description(&self) -> &str {
unsafe { unsafe { utils::optional_str_from_c_ptr((*self.as_ptr()).long_name).unwrap_or("") }
let long_name = (*self.as_ptr()).long_name;
if long_name.is_null() {
""
} else {
from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes())
}
}
} }
pub fn extensions(&self) -> Vec<&str> { pub fn extensions(&self) -> Vec<&str> {
@ -50,9 +41,7 @@ impl Output {
if ptr.is_null() { if ptr.is_null() {
Vec::new() Vec::new()
} else { } else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()) utils::str_from_c_ptr(ptr).split(',').collect()
.split(',')
.collect()
} }
} }
} }
@ -64,9 +53,7 @@ impl Output {
if ptr.is_null() { if ptr.is_null() {
Vec::new() Vec::new()
} else { } else {
from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()) utils::str_from_c_ptr(ptr).split(',').collect()
.split(',')
.collect()
} }
} }
} }

View File

@ -15,12 +15,12 @@ pub use self::format::{Input, Output};
pub mod network; pub mod network;
use std::ffi::{CStr, CString}; use std::ffi::CString;
use std::path::Path; use std::path::Path;
use std::ptr; use std::ptr;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
use crate::{Dictionary, Error}; use crate::{Dictionary, Error};
#[cfg(not(feature = "ffmpeg_5_0"))] #[cfg(not(feature = "ffmpeg_5_0"))]
@ -49,11 +49,11 @@ pub fn version() -> u32 {
} }
pub fn configuration() -> &'static str { pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avformat_configuration()).to_bytes()) } unsafe { utils::str_from_c_ptr(avformat_configuration()) }
} }
pub fn license() -> &'static str { pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avformat_license()).to_bytes()) } unsafe { utils::str_from_c_ptr(avformat_license()) }
} }
// XXX: use to_cstring when stable // XXX: use to_cstring when stable

View File

@ -77,6 +77,8 @@ pub use crate::filter::Filter;
pub mod software; pub mod software;
pub(crate) mod utils;
fn init_error() { fn init_error() {
util::error::register_all(); util::error::register_all();
} }

View File

@ -18,19 +18,17 @@ pub use self::context::Context;
mod extensions; mod extensions;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
pub fn version() -> u32 { pub fn version() -> u32 {
unsafe { swresample_version() } unsafe { swresample_version() }
} }
pub fn configuration() -> &'static str { pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swresample_configuration()).to_bytes()) } unsafe { utils::str_from_c_ptr(swresample_configuration()) }
} }
pub fn license() -> &'static str { pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swresample_license()).to_bytes()) } unsafe { utils::str_from_c_ptr(swresample_license()) }
} }

View File

@ -17,19 +17,17 @@ pub use self::context::Context;
mod extensions; mod extensions;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
pub fn version() -> u32 { pub fn version() -> u32 {
unsafe { swscale_version() } unsafe { swscale_version() }
} }
pub fn configuration() -> &'static str { pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swscale_configuration()).to_bytes()) } unsafe { utils::str_from_c_ptr(swscale_configuration()) }
} }
pub fn license() -> &'static str { pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(swscale_license()).to_bytes()) } unsafe { utils::str_from_c_ptr(swscale_license()) }
} }

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorPrimaries::*; use crate::ffi::AVColorPrimaries::*;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -40,8 +38,7 @@ impl Primaries {
} }
unsafe { unsafe {
let ptr = av_color_primaries_name((*self).into()); let ptr = av_color_primaries_name((*self).into());
ptr.as_ref() utils::optional_str_from_c_ptr(ptr)
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
} }
} }
} }

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorRange::*; use crate::ffi::AVColorRange::*;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -21,8 +19,7 @@ impl Range {
} }
unsafe { unsafe {
let ptr = av_color_range_name((*self).into()); let ptr = av_color_range_name((*self).into());
ptr.as_ref() utils::optional_str_from_c_ptr(ptr)
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
} }
} }
} }

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorSpace::*; use crate::ffi::AVColorSpace::*;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -43,8 +41,7 @@ impl Space {
} }
unsafe { unsafe {
let ptr = av_color_space_name((*self).into()); let ptr = av_color_space_name((*self).into());
ptr.as_ref() utils::optional_str_from_c_ptr(ptr)
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
} }
} }
} }

View File

@ -1,8 +1,6 @@
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::AVColorTransferCharacteristic::*; use crate::ffi::AVColorTransferCharacteristic::*;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -37,8 +35,7 @@ impl TransferCharacteristic {
} }
unsafe { unsafe {
let ptr = av_color_transfer_name((*self).into()); let ptr = av_color_transfer_name((*self).into());
ptr.as_ref() utils::optional_str_from_c_ptr(ptr)
.map(|ptr| from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
} }
} }
} }

View File

@ -1,9 +1,9 @@
use std::ffi::{CStr, CString}; use std::ffi::CString;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ptr; use std::ptr;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
pub struct Iter<'a> { pub struct Iter<'a> {
ptr: *const AVDictionary, ptr: *const AVDictionary,
@ -32,8 +32,8 @@ impl<'a> Iterator for Iter<'a> {
let entry = av_dict_get(self.ptr, empty.as_ptr(), self.cur, AV_DICT_IGNORE_SUFFIX); let entry = av_dict_get(self.ptr, empty.as_ptr(), self.cur, AV_DICT_IGNORE_SUFFIX);
if !entry.is_null() { if !entry.is_null() {
let key = from_utf8_unchecked(CStr::from_ptr((*entry).key).to_bytes()); let key = utils::str_from_c_ptr((*entry).key);
let val = from_utf8_unchecked(CStr::from_ptr((*entry).value).to_bytes()); let val = utils::str_from_c_ptr((*entry).value);
self.cur = entry; self.cur = entry;

View File

@ -1,10 +1,11 @@
use std::error; use std::error;
use std::ffi::{CStr, CString, NulError}; use std::ffi::{CString, NulError};
use std::fmt; use std::fmt;
use std::str::{from_utf8_unchecked, FromStr}; use std::str::FromStr;
use crate::ffi::AVPixelFormat::*; use crate::ffi::AVPixelFormat::*;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -448,7 +449,7 @@ impl Descriptor {
} }
pub fn name(self) -> &'static str { pub fn name(self) -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) } unsafe { utils::str_from_c_ptr((*self.as_ptr()).name) }
} }
pub fn nb_components(self) -> u8 { pub fn nb_components(self) -> u8 {

View File

@ -1,11 +1,11 @@
use std::ffi::{CStr, CString}; use std::ffi::CString;
use std::ops::Index; use std::ops::Index;
use std::ptr; use std::ptr;
use std::slice; use std::slice;
use std::str::from_utf8_unchecked;
use crate::ffi::AVSampleFormat::*; use crate::ffi::AVSampleFormat::*;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
use libc::{c_int, c_void}; use libc::{c_int, c_void};
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -33,9 +33,7 @@ pub enum Type {
impl Sample { impl Sample {
#[inline] #[inline]
pub fn name(&self) -> &'static str { pub fn name(&self) -> &'static str {
unsafe { unsafe { utils::str_from_c_ptr(av_get_sample_fmt_name((*self).into())) }
from_utf8_unchecked(CStr::from_ptr(av_get_sample_fmt_name((*self).into())).to_bytes())
}
} }
#[inline] #[inline]

View File

@ -1,11 +1,10 @@
use std::ffi::CStr;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::slice; use std::slice;
use std::str::from_utf8_unchecked;
use super::Frame; use super::Frame;
use crate::ffi::AVFrameSideDataType::*; use crate::ffi::AVFrameSideDataType::*;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
use crate::DictionaryRef; use crate::DictionaryRef;
#[cfg(feature = "serialize")] #[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -74,9 +73,7 @@ pub enum Type {
impl Type { impl Type {
#[inline] #[inline]
pub fn name(&self) -> &'static str { pub fn name(&self) -> &'static str {
unsafe { unsafe { utils::str_from_c_ptr(av_frame_side_data_name((*self).into())) }
from_utf8_unchecked(CStr::from_ptr(av_frame_side_data_name((*self).into())).to_bytes())
}
} }
} }

View File

@ -16,10 +16,8 @@ pub mod range;
pub mod rational; pub mod rational;
pub mod time; pub mod time;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;
use crate::ffi::*; use crate::ffi::*;
use crate::utils;
#[inline(always)] #[inline(always)]
pub fn version() -> u32 { pub fn version() -> u32 {
@ -28,10 +26,10 @@ pub fn version() -> u32 {
#[inline(always)] #[inline(always)]
pub fn configuration() -> &'static str { pub fn configuration() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avutil_configuration()).to_bytes()) } unsafe { utils::str_from_c_ptr(avutil_configuration()) }
} }
#[inline(always)] #[inline(always)]
pub fn license() -> &'static str { pub fn license() -> &'static str {
unsafe { from_utf8_unchecked(CStr::from_ptr(avutil_license()).to_bytes()) } unsafe { utils::str_from_c_ptr(avutil_license()) }
} }

21
src/utils.rs Normal file
View File

@ -0,0 +1,21 @@
//! Internal utils, not related to `avutil`
use std::ffi::CStr;
/// `ptr` must be non-null and valid.
/// Ensure that the returned lifetime is correctly bounded.
#[inline]
pub unsafe fn str_from_c_ptr<'s>(ptr: *const libc::c_char) -> &'s str {
unsafe { std::str::from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()) }
}
/// `ptr` must be null or valid.
/// Ensure that the returned lifetime is correctly bounded.
#[inline]
pub unsafe fn optional_str_from_c_ptr<'s>(ptr: *const libc::c_char) -> Option<&'s str> {
if ptr.is_null() {
None
} else {
Some(str_from_c_ptr(ptr))
}
}