Skip to main content

vapoursynth4_rs/
api.rs

1/*
2 This Source Code Form is subject to the terms of the Mozilla Public
3 License, v. 2.0. If a copy of the MPL was not distributed with this
4 file, You can obtain one at http://mozilla.org/MPL/2.0/.
5*/
6
7use std::ops::Deref;
8
9use vapoursynth4_sys::vs_make_version;
10
11use crate::ffi;
12
13use self::error::ApiNotFound;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16#[repr(transparent)]
17pub struct Api(*const ffi::VSAPI);
18
19impl Api {
20    /// Creates a new `Api` instance with the specified major and minor version.
21    ///
22    /// # Errors
23    ///
24    /// Returns `ApiNotFound` if the requested API version is not supported by the linked `VapourSynth` library.
25    #[cfg(feature = "link-vs")]
26    pub fn new(major: u16, minor: u16) -> Result<Self, ApiNotFound> {
27        let ptr = unsafe { ffi::getVapourSynthAPI(vs_make_version(major, minor)) };
28        if ptr.is_null() {
29            Err(ApiNotFound { major, minor })
30        } else {
31            Ok(Self(ptr))
32        }
33    }
34
35    pub(crate) unsafe fn from_ptr(ptr: *const ffi::VSAPI) -> Self {
36        Self(ptr)
37    }
38}
39
40impl Deref for Api {
41    type Target = ffi::VSAPI;
42
43    fn deref(&self) -> &Self::Target {
44        unsafe { &*self.0 }
45    }
46}
47
48#[cfg(feature = "link-vs")]
49impl Default for Api {
50    /// Creates a new `Api` instance with the default version.
51    ///
52    /// # Panics
53    ///
54    /// Internal error indicates that something went wrong with the linked `VapourSynth` library.
55    fn default() -> Self {
56        Self::new(ffi::VAPOURSYNTH_API_MAJOR, ffi::VAPOURSYNTH_API_MINOR).unwrap()
57    }
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
61#[repr(transparent)]
62pub struct VssApi(*const ffi::VSSCRIPTAPI);
63
64impl VssApi {
65    /// Creates a new `VssApi` instance with the specified major and minor version.
66    ///
67    /// # Errors
68    ///
69    /// Returns `ApiNotFound` if the requested API version is not supported by the linked `VapourSynth` library.
70    #[cfg(feature = "link-vsscript")]
71    pub fn new(major: u16, minor: u16) -> Result<Self, ApiNotFound> {
72        let ptr = unsafe { ffi::getVSScriptAPI(vs_make_version(major, minor)) };
73        (!ptr.is_null())
74            .then_some(Self(ptr))
75            .ok_or(ApiNotFound { major, minor })
76    }
77
78    #[allow(unused)]
79    pub(crate) unsafe fn from_ptr(ptr: *const ffi::VSSCRIPTAPI) -> Self {
80        Self(ptr.cast_mut())
81    }
82
83    /// Detailed message explaining why the most recent [`VssApi::new()`] failed,
84    /// or [`None`] if it succeeded.
85    ///
86    /// [`ApiNotFound`] only reports the version that was asked for; this reports
87    /// what actually went wrong, typically a failure to locate or load Python.
88    ///
89    /// The message is copied out because the library keeps it in a static buffer
90    /// that the next `VssApi::new()` call overwrites.
91    #[cfg(all(feature = "link-vsscript", feature = "vsscript-43"))]
92    #[must_use]
93    pub fn last_error() -> Option<std::ffi::CString> {
94        let ptr = unsafe { ffi::getVSScriptAPILastError() };
95        (!ptr.is_null()).then(|| unsafe { std::ffi::CStr::from_ptr(ptr) }.to_owned())
96    }
97}
98
99impl Deref for VssApi {
100    type Target = ffi::VSSCRIPTAPI;
101
102    fn deref(&self) -> &Self::Target {
103        unsafe { &*self.0 }
104    }
105}
106
107#[cfg(feature = "link-vsscript")]
108impl Default for VssApi {
109    /// Creates a new `Api` instance with the default version.
110    ///
111    /// # Panics
112    ///
113    /// Internal error indicates that something went wrong with the linked `VapourSynth` library.
114    fn default() -> Self {
115        Self::new(ffi::VSSCRIPT_API_MAJOR, ffi::VSSCRIPT_API_MINOR).unwrap()
116    }
117}
118
119pub mod error {
120    use thiserror::Error;
121
122    #[derive(Error, Debug, Clone, Copy, PartialEq, Eq, Hash)]
123    #[error(
124        "Request API with version {major}.{minor} failed. \
125        Please check if the version is supported by the linked VapourSynth library."
126    )]
127    pub struct ApiNotFound {
128        pub major: u16,
129        pub minor: u16,
130    }
131}