bindings/php/src/lib.rs (77 lines of code) (raw):
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
use ::opendal as od;
use ext_php_rs::binary::Binary;
use ext_php_rs::convert::FromZval;
use ext_php_rs::exception::PhpException;
use ext_php_rs::flags::DataType;
use ext_php_rs::prelude::*;
use ext_php_rs::types::Zval;
use std::collections::HashMap;
use std::str::FromStr;
#[php_class(name = "OpenDAL\\Operator")]
pub struct Operator(od::BlockingOperator);
#[php_impl(rename_methods = "none")]
impl Operator {
pub fn __construct(scheme_str: String, config: HashMap<String, String>) -> PhpResult<Self> {
let scheme = od::Scheme::from_str(&scheme_str).map_err(format_php_err)?;
let op = od::Operator::via_map(scheme, config).map_err(format_php_err)?;
Ok(Operator(op.blocking()))
}
/// Write string into given path.
pub fn write(&self, path: &str, content: String) -> PhpResult<()> {
self.0.write(path, content).map_err(format_php_err)
}
/// Write bytes into given path, binary safe.
pub fn write_binary(&self, path: &str, content: Vec<u8>) -> PhpResult<()> {
self.0.write(path, content).map_err(format_php_err)
}
/// Read the whole path into bytes, binary safe.
pub fn read(&self, path: &str) -> PhpResult<Binary<u8>> {
self.0.read(path).map_err(format_php_err).map(Binary::from)
}
/// Check if this path exists or not, return 1 if exists, 0 otherwise.
pub fn is_exist(&self, path: &str) -> PhpResult<u8> {
self.0
.is_exist(path)
.map_err(format_php_err)
.map(|b| if b { 1 } else { 0 })
}
/// Get current path's metadata **without cache** directly.
///
/// # Notes
///
/// Use `stat` if you:
///
/// - Want detect the outside changes of path.
/// - Don't want to read from cached metadata.
pub fn stat(&self, path: &str) -> PhpResult<Metadata> {
self.0.stat(path).map_err(format_php_err).map(Metadata)
}
/// Delete given path.
///
/// # Notes
///
/// - Delete not existing error won't return errors.
pub fn delete(&self, path: &str) -> PhpResult<()> {
self.0.delete(path).map_err(format_php_err)
}
/// Create a dir at given path.
///
/// # Notes
///
/// To indicate that a path is a directory, it is compulsory to include
/// a trailing / in the path. Failure to do so may result in
/// `NotADirectory` error being returned by OpenDAL.
///
/// # Behavior
///
/// - Create on existing dir will succeed.
/// - Create dir is always recursive, works like `mkdir -p`
pub fn create_dir(&self, path: &str) -> PhpResult<()> {
self.0.create_dir(path).map_err(format_php_err)
}
}
#[php_class(name = "OpenDAL\\Metadata")]
pub struct Metadata(od::Metadata);
#[php_impl(rename_methods = "none")]
impl Metadata {
#[getter]
pub fn content_disposition(&self) -> Option<String> {
self.0.content_disposition().map(|s| s.to_string())
}
/// Content length of this entry.
#[getter]
pub fn content_length(&self) -> u64 {
self.0.content_length()
}
/// Content MD5 of this entry.
#[getter]
pub fn content_md5(&self) -> Option<String> {
self.0.content_md5().map(|s| s.to_string())
}
/// Content Type of this entry.
#[getter]
pub fn content_type(&self) -> Option<String> {
self.0.content_type().map(|s| s.to_string())
}
/// ETag of this entry.
#[getter]
pub fn etag(&self) -> Option<String> {
self.0.etag().map(|s| s.to_string())
}
/// mode represent this entry's mode.
#[getter]
pub fn mode(&self) -> EntryMode {
EntryMode(self.0.mode())
}
}
#[php_class(name = "OpenDAL\\EntryMode")]
pub struct EntryMode(od::EntryMode);
impl<'b> FromZval<'b> for EntryMode {
const TYPE: DataType = DataType::Object(Some("OpenDAL\\EntryMode"));
fn from_zval(zval: &'b Zval) -> Option<Self> {
zval.object().and_then(|obj| obj.get_property("mode").ok())
}
}
#[php_impl(rename_methods = "none")]
impl EntryMode {
#[getter]
pub fn is_dir(&self) -> u8 {
match self.0.is_dir() {
true => 1,
false => 0,
}
}
#[getter]
pub fn is_file(&self) -> u8 {
match self.0.is_file() {
true => 1,
false => 0,
}
}
}
fn format_php_err(e: od::Error) -> PhpException {
// @todo use custom exception, we cannot use custom exception now,
// see https://github.com/davidcole1340/ext-php-rs/issues/262
PhpException::default(e.to_string())
}
#[php_module]
pub fn get_module(module: ModuleBuilder) -> ModuleBuilder {
module
}