diff options
| -rw-r--r-- | crates/shirabe-php-shim/src/array.rs | 114 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/src/fs.rs | 115 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/src/runtime.rs | 4 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/src/string.rs | 203 | ||||
| -rw-r--r-- | crates/shirabe-php-shim/src/var.rs | 32 |
5 files changed, 229 insertions, 239 deletions
diff --git a/crates/shirabe-php-shim/src/array.rs b/crates/shirabe-php-shim/src/array.rs index c4cb2d6e..00e44da3 100644 --- a/crates/shirabe-php-shim/src/array.rs +++ b/crates/shirabe-php-shim/src/array.rs @@ -2,21 +2,21 @@ use crate::PhpMixed; use crate::php_to_string; use indexmap::IndexMap; -pub fn array_values<V: Clone>(_array: &IndexMap<String, V>) -> Vec<V> { - _array.values().cloned().collect() +pub fn array_values<V: Clone>(array: &IndexMap<String, V>) -> Vec<V> { + array.values().cloned().collect() } -pub fn array_keys<V>(_array: &IndexMap<String, V>) -> Vec<String> { - _array.keys().cloned().collect() +pub fn array_keys<V>(array: &IndexMap<String, V>) -> Vec<String> { + array.keys().cloned().collect() } -pub fn array_push(_array: &mut Vec<String>, _value: String) -> i64 { - _array.push(_value); - _array.len() as i64 +pub fn array_push(array: &mut Vec<String>, value: String) -> i64 { + array.push(value); + array.len() as i64 } -pub fn array_search_in_vec(_needle: &str, _haystack: &[String]) -> Option<usize> { - _haystack.iter().position(|s| s.as_str() == _needle) +pub fn array_search_in_vec(needle: &str, haystack: &[String]) -> Option<usize> { + haystack.iter().position(|s| s.as_str() == needle) } pub fn array_map_str_fn<F: Fn(&str) -> String>(_callback: F, _array: &[String]) -> Vec<String> { @@ -136,10 +136,10 @@ pub fn array_merge_map<V>( result } -pub fn array_diff(_array1: &[String], _array2: &[String]) -> Vec<String> { - _array1 +pub fn array_diff(array1: &[String], array2: &[String]) -> Vec<String> { + array1 .iter() - .filter(|&x| !_array2.contains(x)) + .filter(|&x| !array2.contains(x)) .cloned() .collect() } @@ -158,12 +158,12 @@ pub fn array_unique<T: Clone + PartialEq>(array: &[T]) -> Vec<T> { } pub fn array_intersect_key( - _array1: &IndexMap<String, PhpMixed>, - _array2: &IndexMap<String, PhpMixed>, + array1: &IndexMap<String, PhpMixed>, + array2: &IndexMap<String, PhpMixed>, ) -> IndexMap<String, PhpMixed> { - _array1 + array1 .iter() - .filter(|(k, _)| _array2.contains_key(k.as_str())) + .filter(|(k, _)| array2.contains_key(k.as_str())) .map(|(k, v)| (k.clone(), v.clone())) .collect() } @@ -260,72 +260,72 @@ pub fn array_search(needle: &str, haystack: &IndexMap<String, String>) -> Option .map(|(key, _)| key.clone()) } -pub fn array_shift<T>(_array: &mut Vec<T>) -> Option<T> { - if _array.is_empty() { +pub fn array_shift<T>(array: &mut Vec<T>) -> Option<T> { + if array.is_empty() { None } else { - Some(_array.remove(0)) + Some(array.remove(0)) } } -pub fn array_pop<T>(_array: &mut Vec<T>) -> Option<T> { - _array.pop() +pub fn array_pop<T>(array: &mut Vec<T>) -> Option<T> { + array.pop() } -pub fn array_unshift<T>(_array: &mut Vec<T>, _value: T) { - _array.insert(0, _value); +pub fn array_unshift<T>(array: &mut Vec<T>, value: T) { + array.insert(0, value); } -pub fn array_reverse<T: Clone>(_array: &[T], _preserve_keys: bool) -> Vec<T> { - _array.iter().rev().cloned().collect() +pub fn array_reverse<T: Clone>(array: &[T], _preserve_keys: bool) -> Vec<T> { + array.iter().rev().cloned().collect() } -pub fn array_filter<T: Clone, F>(_array: &[T], _callback: F) -> Vec<T> +pub fn array_filter<T: Clone, F>(array: &[T], callback: F) -> Vec<T> where F: Fn(&T) -> bool, { - _array.iter().filter(|&x| _callback(x)).cloned().collect() + array.iter().filter(|&x| callback(x)).cloned().collect() } pub fn array_filter_map<F>( - _array: &IndexMap<String, PhpMixed>, - _callback: F, + array: &IndexMap<String, PhpMixed>, + callback: F, ) -> IndexMap<String, PhpMixed> where F: Fn(&PhpMixed) -> bool, { - _array + array .iter() - .filter(|&(_, v)| _callback(v)) + .filter(|&(_, v)| callback(v)) .map(|(k, v)| (k.clone(), v.clone())) .collect() } -pub fn array_all<T, F>(_array: &[T], _callback: F) -> bool +pub fn array_all<T, F>(array: &[T], callback: F) -> bool where F: Fn(&T) -> bool, { - _array.iter().all(_callback) + array.iter().all(callback) } -pub fn array_any<T, F>(_array: &[T], _callback: F) -> bool +pub fn array_any<T, F>(array: &[T], callback: F) -> bool where F: Fn(&T) -> bool, { - _array.iter().any(_callback) + array.iter().any(callback) } -pub fn array_reduce<T, U, F>(_array: &[T], _callback: F, _initial: U) -> U +pub fn array_reduce<T, U, F>(array: &[T], callback: F, initial: U) -> U where F: Fn(U, &T) -> U, { - _array.iter().fold(_initial, _callback) + array.iter().fold(initial, callback) } -pub fn array_intersect<T: Clone + PartialEq>(_array1: &[T], _array2: &[T]) -> Vec<T> { - _array1 +pub fn array_intersect<T: Clone + PartialEq>(array1: &[T], array2: &[T]) -> Vec<T> { + array1 .iter() - .filter(|&x| _array2.contains(x)) + .filter(|&x| array2.contains(x)) .cloned() .collect() } @@ -365,16 +365,16 @@ pub fn array_flip(array: &PhpMixed) -> PhpMixed { PhpMixed::Array(result) } -pub fn array_flip_strings(_array: &[String]) -> IndexMap<String, PhpMixed> { - _array +pub fn array_flip_strings(array: &[String]) -> IndexMap<String, PhpMixed> { + array .iter() .enumerate() .map(|(i, s)| (s.clone(), PhpMixed::Int(i as i64))) .collect() } -pub fn array_key_exists<V>(_key: &str, _array: &IndexMap<String, V>) -> bool { - _array.contains_key(_key) +pub fn array_key_exists<V>(key: &str, array: &IndexMap<String, V>) -> bool { + array.contains_key(key) } pub fn array_is_list(array: &PhpMixed) -> bool { @@ -518,24 +518,24 @@ pub fn array_slice<V: Clone>( .collect() } -pub fn array_map<T, U, F>(_callback: F, _array: &[T]) -> Vec<U> +pub fn array_map<T, U, F>(callback: F, array: &[T]) -> Vec<U> where F: Fn(&T) -> U, { - _array.iter().map(_callback).collect() + array.iter().map(callback).collect() } -pub fn array_chunk<T: Clone>(_array: &[T], _size: i64, _preserve_keys: bool) -> Vec<Vec<T>> { - _array.chunks(_size as usize).map(|c| c.to_vec()).collect() +pub fn array_chunk<T: Clone>(array: &[T], size: i64, _preserve_keys: bool) -> Vec<Vec<T>> { + array.chunks(size as usize).map(|c| c.to_vec()).collect() } pub fn array_diff_key( - _array1: IndexMap<String, PhpMixed>, - _array2: &IndexMap<String, PhpMixed>, + array1: IndexMap<String, PhpMixed>, + array2: &IndexMap<String, PhpMixed>, ) -> IndexMap<String, PhpMixed> { - _array1 + array1 .into_iter() - .filter(|(k, _)| !_array2.contains_key(k.as_str())) + .filter(|(k, _)| !array2.contains_key(k.as_str())) .collect() } @@ -663,8 +663,8 @@ where array.sort_by(|_, v1, _, v2| compare(v1, v2).cmp(&0)); } -pub fn sort<T: Ord>(_array: &mut Vec<T>) { - _array.sort(); +pub fn sort<T: Ord>(array: &mut [T]) { + array.sort(); } pub const SORT_REGULAR: i64 = 0; @@ -673,12 +673,12 @@ pub const SORT_STRING: i64 = 2; pub const SORT_NATURAL: i64 = 6; pub const SORT_FLAG_CASE: i64 = 8; -pub fn usort<T, F>(_array: &mut Vec<T>, _compare: F) +pub fn usort<T, F>(array: &mut [T], compare: F) where F: FnMut(&T, &T) -> i64, { - let mut compare = _compare; - _array.sort_by(|a, b| compare(a, b).cmp(&0)); + let mut compare = compare; + array.sort_by(|a, b| compare(a, b).cmp(&0)); } pub fn ksort<V>(array: &mut IndexMap<String, V>) { diff --git a/crates/shirabe-php-shim/src/fs.rs b/crates/shirabe-php-shim/src/fs.rs index c2b0dc41..a948a6f2 100644 --- a/crates/shirabe-php-shim/src/fs.rs +++ b/crates/shirabe-php-shim/src/fs.rs @@ -205,28 +205,25 @@ impl RecursiveIteratorFileInfo { } pub fn recursive_directory_iterator( - _path: impl AsRef<std::path::Path>, - _flags: i64, + path: impl AsRef<std::path::Path>, + flags: i64, ) -> Result<RecursiveDirectoryIterator, UnexpectedValueException> { - let root = _path.as_ref().to_path_buf(); + let root = path.as_ref().to_path_buf(); if !root.is_dir() { return Err(UnexpectedValueException::new(format!( "RecursiveDirectoryIterator::__construct({}): Failed to open directory", root.display() ))); } - Ok(RecursiveDirectoryIterator { - root, - flags: _flags, - }) + Ok(RecursiveDirectoryIterator { root, flags }) } pub fn recursive_iterator_iterator( - _iter: RecursiveDirectoryIterator, - _mode: i64, + iter: RecursiveDirectoryIterator, + mode: i64, ) -> RecursiveIteratorIterator { let mut entries = Vec::new(); - rii_walk(&_iter.root, &_iter.root, _iter.flags, _mode, &mut entries); + rii_walk(&iter.root, &iter.root, iter.flags, mode, &mut entries); RecursiveIteratorIterator { entries, cursor: std::cell::Cell::new(0), @@ -712,9 +709,9 @@ pub fn fflush(stream: &PhpResource) -> bool { } } -pub fn lstat(_filename: impl AsRef<std::path::Path>) -> Option<IndexMap<String, PhpMixed>> { +pub fn lstat(filename: impl AsRef<std::path::Path>) -> Option<IndexMap<String, PhpMixed>> { use std::os::unix::fs::MetadataExt; - let m = std::fs::symlink_metadata(_filename).ok()?; + let m = std::fs::symlink_metadata(filename).ok()?; Some(stat_fields_map([ ("dev", m.dev() as i64), ("ino", m.ino() as i64), @@ -789,16 +786,16 @@ pub fn touch3(path: impl AsRef<std::path::Path>, mtime: i64, atime: i64) -> bool touch_impl(path.as_ref(), mtime, atime) } -pub fn chmod(_path: impl AsRef<std::path::Path>, _mode: u32) -> bool { +pub fn chmod(path: impl AsRef<std::path::Path>, mode: u32) -> bool { use std::os::unix::fs::PermissionsExt; - std::fs::set_permissions(_path.as_ref(), std::fs::Permissions::from_mode(_mode)).is_ok() + std::fs::set_permissions(path.as_ref(), std::fs::Permissions::from_mode(mode)).is_ok() } -pub fn fileperms(_path: impl AsRef<std::path::Path>) -> i64 { +pub fn fileperms(path: impl AsRef<std::path::Path>) -> i64 { use std::os::unix::fs::MetadataExt; // PHP returns the full st_mode (file type bits included). // TODO(phase-c): PHP returns false on error; this i64 signature reports 0 instead. - std::fs::metadata(_path.as_ref()) + std::fs::metadata(path.as_ref()) .map(|m| m.mode() as i64) .unwrap_or(0) } @@ -811,12 +808,12 @@ pub fn file_exists(path: impl AsRef<std::path::Path>) -> bool { path.as_ref().exists() } -pub fn is_writable(_path: impl AsRef<std::path::Path>) -> bool { - nix::unistd::access(_path.as_ref(), nix::unistd::AccessFlags::W_OK).is_ok() +pub fn is_writable(path: impl AsRef<std::path::Path>) -> bool { + nix::unistd::access(path.as_ref(), nix::unistd::AccessFlags::W_OK).is_ok() } -pub fn is_readable(_path: impl AsRef<std::path::Path>) -> bool { - let path = _path.as_ref(); +pub fn is_readable(path: impl AsRef<std::path::Path>) -> bool { + let path = path.as_ref(); match std::fs::metadata(path) { Ok(meta) => { if meta.is_dir() { @@ -829,8 +826,8 @@ pub fn is_readable(_path: impl AsRef<std::path::Path>) -> bool { } } -pub fn is_executable(_path: impl AsRef<std::path::Path>) -> bool { - nix::unistd::access(_path.as_ref(), nix::unistd::AccessFlags::X_OK).is_ok() +pub fn is_executable(path: impl AsRef<std::path::Path>) -> bool { + nix::unistd::access(path.as_ref(), nix::unistd::AccessFlags::X_OK).is_ok() } pub fn is_file(path: impl AsRef<std::path::Path>) -> bool { @@ -856,16 +853,16 @@ pub fn readlink(path: impl AsRef<std::path::Path>) -> Option<String> { .map(|target| target.to_string_lossy().into_owned()) } -pub fn fileatime(_filename: impl AsRef<std::path::Path>) -> Option<i64> { - std::fs::metadata(_filename.as_ref()) +pub fn fileatime(filename: impl AsRef<std::path::Path>) -> Option<i64> { + std::fs::metadata(filename.as_ref()) .ok() .and_then(|m| m.accessed().ok()) .and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok()) .map(|d| d.as_secs() as i64) } -pub fn filemtime(_filename: impl AsRef<std::path::Path>) -> Option<i64> { - std::fs::metadata(_filename.as_ref()) +pub fn filemtime(filename: impl AsRef<std::path::Path>) -> Option<i64> { + std::fs::metadata(filename.as_ref()) .ok() .and_then(|m| m.modified().ok()) .and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok()) @@ -876,21 +873,19 @@ pub fn unlink(path: impl AsRef<std::path::Path>) -> Result<(), std::io::Error> { std::fs::remove_file(path) } -pub fn unlink_silent(_path: impl AsRef<std::path::Path>) -> bool { +pub fn unlink_silent(path: impl AsRef<std::path::Path>) -> bool { // PHP's `@unlink`: delete the file, suppressing any warning. - std::fs::remove_file(_path.as_ref()).is_ok() + std::fs::remove_file(path.as_ref()).is_ok() } -pub fn file_put_contents(_path: &str, _data: &[u8]) -> Option<i64> { - std::fs::write(_path, _data) - .ok() - .map(|_| _data.len() as i64) +pub fn file_put_contents(path: &str, data: &[u8]) -> Option<i64> { + std::fs::write(path, data).ok().map(|_| data.len() as i64) } -pub fn file_put_contents3(_filename: &str, _data: &str, _flags: i64) -> Option<i64> { +pub fn file_put_contents3(filename: &str, data: &str, flags: i64) -> Option<i64> { // TODO(phase-c): the LOCK_EX and FILE_USE_INCLUDE_PATH flags are ignored; only FILE_APPEND is // honored. - let append = _flags & FILE_APPEND != 0; + let append = flags & FILE_APPEND != 0; let mut opts = std::fs::OpenOptions::new(); opts.write(true).create(true); if append { @@ -898,9 +893,9 @@ pub fn file_put_contents3(_filename: &str, _data: &str, _flags: i64) -> Option<i } else { opts.truncate(true); } - let mut file = opts.open(_filename).ok()?; - file.write_all(_data.as_bytes()).ok()?; - Some(_data.len() as i64) + let mut file = opts.open(filename).ok()?; + file.write_all(data.as_bytes()).ok()?; + Some(data.len() as i64) } pub fn file_get_contents(path: impl AsRef<std::path::Path>) -> Option<String> { @@ -916,25 +911,25 @@ pub fn file_get_contents(path: impl AsRef<std::path::Path>) -> Option<String> { } pub fn file_get_contents5( - _path: &str, + path: &str, _use_include_path: bool, _context: PhpMixed, - _offset: i64, - _length: Option<i64>, + offset: i64, + length: Option<i64>, ) -> Option<String> { // TODO(phase-c): the stream $context and FILE_USE_INCLUDE_PATH are ignored; only $offset and // $length are applied (to the file read from the local filesystem). // PHP supports the file:// stream wrapper; strip it to read the local file. - let path = _path.strip_prefix("file://").unwrap_or(_path); + let path = path.strip_prefix("file://").unwrap_or(path); let bytes = std::fs::read(path).ok()?; let len = bytes.len() as i64; - let start = if _offset < 0 { - (len + _offset).max(0) + let start = if offset < 0 { + (len + offset).max(0) } else { - _offset.min(len) + offset.min(len) } as usize; let slice = &bytes[start..]; - let slice = match _length { + let slice = match length { Some(l) if l >= 0 => &slice[..(l as usize).min(slice.len())], _ => slice, }; @@ -947,21 +942,21 @@ pub fn getcwd() -> Option<String> { .map(|p| p.to_string_lossy().into_owned()) } -pub fn chdir(_path: impl AsRef<std::path::Path>) -> anyhow::Result<()> { - Ok(std::env::set_current_dir(_path.as_ref())?) +pub fn chdir(path: impl AsRef<std::path::Path>) -> anyhow::Result<()> { + Ok(std::env::set_current_dir(path.as_ref())?) } -pub fn glob(_pattern: &str) -> Vec<String> { - glob_with_flags(_pattern, 0) +pub fn glob(pattern: &str) -> Vec<String> { + glob_with_flags(pattern, 0) } pub const FILE_SKIP_EMPTY_LINES: i64 = 4; -pub fn file(_filename: &str, _flags: i64) -> Option<Vec<String>> { - let content = std::fs::read(_filename).ok()?; +pub fn file(filename: &str, flags: i64) -> Option<Vec<String>> { + let content = std::fs::read(filename).ok()?; let s = String::from_utf8_lossy(&content); - let ignore_newlines = _flags & FILE_IGNORE_NEW_LINES != 0; - let skip_empty = _flags & FILE_SKIP_EMPTY_LINES != 0; + let ignore_newlines = flags & FILE_IGNORE_NEW_LINES != 0; + let skip_empty = flags & FILE_SKIP_EMPTY_LINES != 0; let mut lines = Vec::new(); // PHP keeps the trailing newline on each element unless FILE_IGNORE_NEW_LINES is set. for line in s.split_inclusive('\n') { @@ -1025,8 +1020,8 @@ pub fn rename( std::fs::rename(old_name, new_name).is_ok() } -pub fn copy(_source: impl AsRef<std::path::Path>, _dest: impl AsRef<std::path::Path>) -> bool { - std::fs::copy(_source.as_ref(), _dest.as_ref()).is_ok() +pub fn copy(source: impl AsRef<std::path::Path>, dest: impl AsRef<std::path::Path>) -> bool { + std::fs::copy(source.as_ref(), dest.as_ref()).is_ok() } pub fn ftruncate(stream: &PhpResource, size: i64) -> bool { @@ -1167,15 +1162,15 @@ pub const GLOB_MARK: i64 = 8; pub const GLOB_ONLYDIR: i64 = 1024; pub const GLOB_BRACE: i64 = 4096; -pub fn glob_with_flags(_pattern: &str, _flags: i64) -> Vec<String> { - let patterns = if _flags & GLOB_BRACE != 0 { - glob_expand_braces(_pattern) +pub fn glob_with_flags(pattern: &str, flags: i64) -> Vec<String> { + let patterns = if flags & GLOB_BRACE != 0 { + glob_expand_braces(pattern) } else { - vec![_pattern.to_string()] + vec![pattern.to_string()] }; let mut results: Vec<String> = Vec::new(); for pattern in patterns { - glob_collect(&pattern, _flags, &mut results); + glob_collect(&pattern, flags, &mut results); } // PHP sorts the result set by default (GLOB_NOSORT is not modeled here). results.sort(); diff --git a/crates/shirabe-php-shim/src/runtime.rs b/crates/shirabe-php-shim/src/runtime.rs index 6b165567..86cbfd74 100644 --- a/crates/shirabe-php-shim/src/runtime.rs +++ b/crates/shirabe-php-shim/src/runtime.rs @@ -334,8 +334,8 @@ pub fn trigger_deprecation(_package: &str, _version: &str, _message: &str, _arg: todo!() } -pub fn usleep(_microseconds: u64) { - std::thread::sleep(std::time::Duration::from_micros(_microseconds)); +pub fn usleep(microseconds: u64) { + std::thread::sleep(std::time::Duration::from_micros(microseconds)); } /// Equivalent to PHP's __DIR__ magic constant diff --git a/crates/shirabe-php-shim/src/string.rs b/crates/shirabe-php-shim/src/string.rs index a322e36f..8cab6eca 100644 --- a/crates/shirabe-php-shim/src/string.rs +++ b/crates/shirabe-php-shim/src/string.rs @@ -14,16 +14,16 @@ pub fn str_replace(search: &str, replace: &str, subject: &str) -> String { subject.replace(search, replace) } -pub fn str_contains(_haystack: &str, _needle: &str) -> bool { - _haystack.contains(_needle) +pub fn str_contains(haystack: &str, needle: &str) -> bool { + haystack.contains(needle) } -pub fn str_starts_with(_haystack: &str, _needle: &str) -> bool { - _haystack.starts_with(_needle) +pub fn str_starts_with(haystack: &str, needle: &str) -> bool { + haystack.starts_with(needle) } -pub fn str_ends_with(_haystack: &str, _needle: &str) -> bool { - _haystack.ends_with(_needle) +pub fn str_ends_with(haystack: &str, needle: &str) -> bool { + haystack.ends_with(needle) } pub fn substr_count(haystack: &str, needle: &str) -> i64 { @@ -48,8 +48,8 @@ pub fn substr_replace(string: &str, replace: &str, start: usize, length: usize) String::from_utf8_lossy(&out).into_owned() } -pub fn str_repeat(_s: &str, _count: usize) -> String { - _s.repeat(_count) +pub fn str_repeat(s: &str, count: usize) -> String { + s.repeat(count) } pub fn str_replace_array(search: &[String], replace: &[String], subject: &str) -> String { @@ -63,29 +63,29 @@ pub fn str_replace_array(search: &[String], replace: &[String], subject: &str) - result } -pub fn str_pad(_input: &str, _length: usize, _pad_string: &str, _pad_type: i64) -> String { +pub fn str_pad(input: &str, length: usize, pad_string: &str, pad_type: i64) -> String { // PHP str_pad() works on bytes: it pads up to `length` bytes by repeating `pad_string`. - let input_len = _input.len(); - if _length <= input_len || _pad_string.is_empty() { - return _input.to_string(); + let input_len = input.len(); + if length <= input_len || pad_string.is_empty() { + return input.to_string(); } - let pad = _pad_string.as_bytes(); + let pad = pad_string.as_bytes(); let make = |n: usize| -> Vec<u8> { (0..n).map(|i| pad[i % pad.len()]).collect() }; - let total = _length - input_len; - let mut out: Vec<u8> = Vec::with_capacity(_length); - match _pad_type { + let total = length - input_len; + let mut out: Vec<u8> = Vec::with_capacity(length); + match pad_type { STR_PAD_LEFT => { out.extend(make(total)); - out.extend_from_slice(_input.as_bytes()); + out.extend_from_slice(input.as_bytes()); } STR_PAD_BOTH => { let left = total / 2; out.extend(make(left)); - out.extend_from_slice(_input.as_bytes()); + out.extend_from_slice(input.as_bytes()); out.extend(make(total - left)); } _ => { - out.extend_from_slice(_input.as_bytes()); + out.extend_from_slice(input.as_bytes()); out.extend(make(total)); } } @@ -96,10 +96,10 @@ pub const STR_PAD_LEFT: i64 = 0; pub const STR_PAD_RIGHT: i64 = 1; pub const STR_PAD_BOTH: i64 = 2; -pub fn str_split(_s: &str, _length: i64) -> Vec<String> { +pub fn str_split(s: &str, length: i64) -> Vec<String> { // PHP str_split() chunks the string by bytes into pieces of `length` bytes. - let length = _length.max(1) as usize; - let bytes = _s.as_bytes(); + let length = length.max(1) as usize; + let bytes = s.as_bytes(); if bytes.is_empty() { return vec![String::new()]; } @@ -109,10 +109,10 @@ pub fn str_split(_s: &str, _length: i64) -> Vec<String> { .collect() } -pub fn str_bitand(_a: &str, _b: &str) -> String { +pub fn str_bitand(a: &str, b: &str) -> String { // PHP's string `&` operator: byte-wise AND, the result truncated to the shorter operand. - let a = _a.as_bytes(); - let b = _b.as_bytes(); + let a = a.as_bytes(); + let b = b.as_bytes(); let n = a.len().min(b.len()); let out: Vec<u8> = (0..n).map(|i| a[i] & b[i]).collect(); String::from_utf8_lossy(&out).into_owned() @@ -132,20 +132,20 @@ pub fn str_replace_arr(search: &[&str], replace: &str, subject: &str) -> String result } -pub fn strcasecmp(_s1: &str, _s2: &str) -> i64 { - _s1.to_ascii_lowercase().cmp(&_s2.to_ascii_lowercase()) as i64 +pub fn strcasecmp(s1: &str, s2: &str) -> i64 { + s1.to_ascii_lowercase().cmp(&s2.to_ascii_lowercase()) as i64 } -pub fn strpos(_haystack: &str, _needle: &str) -> Option<usize> { - _haystack.find(_needle) +pub fn strpos(haystack: &str, needle: &str) -> Option<usize> { + haystack.find(needle) } -pub fn strtoupper(_s: &str) -> String { - _s.to_ascii_uppercase() +pub fn strtoupper(s: &str) -> String { + s.to_ascii_uppercase() } -pub fn strlen(_s: &str) -> i64 { - _s.len() as i64 +pub fn strlen(s: &str) -> i64 { + s.len() as i64 } pub fn strtr(str: &str, from: &str, to: &str) -> String { @@ -175,8 +175,8 @@ pub fn strnatcasecmp(s1: &str, s2: &str) -> i64 { strnatcmp_ex(s1.as_bytes(), s2.as_bytes(), true) } -pub fn strrpos(_haystack: &str, _needle: &str) -> Option<usize> { - _haystack.rfind(_needle) +pub fn strrpos(haystack: &str, needle: &str) -> Option<usize> { + haystack.rfind(needle) } // Byte-based, matching PHP: strrev() reverses the bytes, not the characters. @@ -186,14 +186,14 @@ pub fn strrev(s: &str) -> String { String::from_utf8_lossy(&bytes).into_owned() } -pub fn strtolower(_s: &str) -> String { - _s.to_ascii_lowercase() +pub fn strtolower(s: &str) -> String { + s.to_ascii_lowercase() } -pub fn stripos(_haystack: &str, _needle: &str) -> Option<usize> { - _haystack +pub fn stripos(haystack: &str, needle: &str) -> Option<usize> { + haystack .to_ascii_lowercase() - .find(_needle.to_ascii_lowercase().as_str()) + .find(needle.to_ascii_lowercase().as_str()) } // Byte-based, matching PHP's array form of strtr: at each position the longest @@ -225,8 +225,8 @@ pub fn strtr_array(s: &str, pairs: &IndexMap<String, String>) -> String { String::from_utf8_lossy(&result).into_owned() } -pub fn strcmp(_s1: &str, _s2: &str) -> i64 { - _s1.cmp(_s2) as i64 +pub fn strcmp(s1: &str, s2: &str) -> i64 { + s1.cmp(s2) as i64 } pub fn strnatcmp(s1: &str, s2: &str) -> i64 { @@ -311,8 +311,8 @@ pub fn substr(s: &str, start: i64, length: Option<i64>) -> String { String::from_utf8_lossy(&bytes[start as usize..end as usize]).into_owned() } -pub fn implode(_glue: &str, _pieces: &[String]) -> String { - _pieces.join(_glue) +pub fn implode(glue: &str, pieces: &[String]) -> String { + pieces.join(glue) } pub fn explode(delimiter: &str, string: &str) -> Vec<String> { @@ -356,13 +356,13 @@ fn canonical_encoding(name: &str) -> String { } } -pub fn mb_convert_encoding(_string: Vec<u8>, _to_encoding: &str, _from_encoding: &str) -> String { - let to = canonical_encoding(_to_encoding); - let from = canonical_encoding(_from_encoding); +pub fn mb_convert_encoding(string: Vec<u8>, to_encoding: &str, from_encoding: &str) -> String { + let to = canonical_encoding(to_encoding); + let from = canonical_encoding(from_encoding); // ASCII is a subset of UTF-8, so converting among ASCII/UTF-8 is a byte-level no-op. Other // encodings need conversion tables that have not been ported yet. if matches!(to.as_str(), "UTF-8" | "ASCII") && matches!(from.as_str(), "UTF-8" | "ASCII") { - return String::from_utf8_lossy(&_string).into_owned(); + return String::from_utf8_lossy(&string).into_owned(); } todo!("mb_convert_encoding {} -> {}", from, to) } @@ -372,27 +372,27 @@ pub fn mb_strlen(s: &str, _encoding: &str) -> i64 { s.chars().count() as i64 } -pub fn mb_check_encoding(_value: &str, _encoding: &str) -> bool { - match _encoding.to_ascii_uppercase().replace('-', "").as_str() { +pub fn mb_check_encoding(value: &str, encoding: &str) -> bool { + match encoding.to_ascii_uppercase().replace('-', "").as_str() { // A Rust &str is, by construction, valid UTF-8. "UTF8" => true, - "ASCII" | "USASCII" => _value.is_ascii(), + "ASCII" | "USASCII" => value.is_ascii(), // Other encodings need the mbstring validation tables, which have not been ported. _ => todo!(), } } pub fn mb_detect_encoding( - _s: &str, - _encodings: Option<Vec<String>>, + s: &str, + encodings: Option<Vec<String>>, _strict: bool, ) -> Option<String> { - // PHP's default detection order is ASCII then UTF-8. `_s` is already valid UTF-8, so detection + // PHP's default detection order is ASCII then UTF-8. `s` is already valid UTF-8, so detection // reduces to: pure-ASCII content matches "ASCII", anything else matches "UTF-8". - let order = _encodings.unwrap_or_else(|| vec!["ASCII".to_string(), "UTF-8".to_string()]); + let order = encodings.unwrap_or_else(|| vec!["ASCII".to_string(), "UTF-8".to_string()]); for enc in order { match canonical_encoding(&enc).as_str() { - "ASCII" if _s.is_ascii() => return Some(enc), + "ASCII" if s.is_ascii() => return Some(enc), "UTF-8" => return Some(enc), _ => {} } @@ -421,13 +421,13 @@ pub fn mb_str_split(s: &str, length: i64) -> Vec<String> { .collect() } -pub fn mb_convert_variables(_to: &str, _from: &str, _vars: &mut Vec<String>) -> Option<String> { - // Converts each variable in place from `_from` to `_to`, returning the source encoding (PHP - // returns the detected source encoding; here `_from` is a single named encoding). - for v in _vars.iter_mut() { - *v = mb_convert_encoding(std::mem::take(v).into_bytes(), _to, _from); +pub fn mb_convert_variables(to: &str, from: &str, vars: &mut [String]) -> Option<String> { + // Converts each variable in place from `from` to `to`, returning the source encoding (PHP + // returns the detected source encoding; here `from` is a single named encoding). + for v in vars.iter_mut() { + *v = mb_convert_encoding(std::mem::take(v).into_bytes(), to, from); } - Some(_from.to_string()) + Some(from.to_string()) } /// Resolve PHP array_slice/substr-style (offset, length) into a `[start, end)` @@ -492,9 +492,9 @@ pub fn urlencode(s: &str) -> String { out } -pub fn base64_encode(_data: impl AsRef<[u8]>) -> String { +pub fn base64_encode(data: impl AsRef<[u8]>) -> String { const TABLE: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - let bytes = _data.as_ref(); + let bytes = data.as_ref(); let mut out = String::with_capacity(bytes.len().div_ceil(3) * 4); for chunk in bytes.chunks(3) { let b1 = chunk.get(1).copied(); @@ -516,11 +516,11 @@ pub fn base64_encode(_data: impl AsRef<[u8]>) -> String { out } -pub fn base64_decode(_data: &str) -> Option<Vec<u8>> { +pub fn base64_decode(data: &str) -> Option<Vec<u8>> { // Non-strict mode (PHP's default $strict = false): characters outside the base64 alphabet are // silently skipped, and padding terminates the input. - let mut sextets: Vec<u8> = Vec::with_capacity(_data.len()); - for &b in _data.as_bytes() { + let mut sextets: Vec<u8> = Vec::with_capacity(data.len()); + for &b in data.as_bytes() { let v = match b { b'A'..=b'Z' => b - b'A', b'a'..=b'z' => b - b'a' + 26, @@ -552,16 +552,16 @@ pub fn base64_decode(_data: &str) -> Option<Vec<u8>> { Some(out) } -pub fn ctype_alnum(_s: &str) -> bool { - !_s.is_empty() && _s.bytes().all(|b| b.is_ascii_alphanumeric()) +pub fn ctype_alnum(s: &str) -> bool { + !s.is_empty() && s.bytes().all(|b| b.is_ascii_alphanumeric()) } pub fn ctype_digit(s: &str) -> bool { !s.is_empty() && s.bytes().all(|b| b.is_ascii_digit()) } -pub fn ord(_c: &str) -> i64 { - _c.as_bytes().first().copied().unwrap_or(0) as i64 +pub fn ord(c: &str) -> i64 { + c.as_bytes().first().copied().unwrap_or(0) as i64 } pub fn ucwords(s: &str) -> String { @@ -589,8 +589,8 @@ fn hex_digit_value(b: u8) -> Option<u8> { } } -pub fn sprintf(_format: &str, _args: &[PhpMixed]) -> String { - let fb = _format.as_bytes(); +pub fn sprintf(format: &str, args: &[PhpMixed]) -> String { + let fb = format.as_bytes(); let mut out = String::new(); let mut i = 0; let mut next_arg = 0usize; @@ -601,7 +601,7 @@ pub fn sprintf(_format: &str, _args: &[PhpMixed]) -> String { while i < fb.len() && fb[i] != b'%' { i += 1; } - out.push_str(&_format[start..i]); + out.push_str(&format[start..i]); continue; } i += 1; @@ -623,7 +623,7 @@ pub fn sprintf(_format: &str, _args: &[PhpMixed]) -> String { k += 1; } if k > i && k < fb.len() && fb[k] == b'$' { - explicit_arg = _format[i..k].parse::<usize>().ok(); + explicit_arg = format[i..k].parse::<usize>().ok(); i = k + 1; } } @@ -661,7 +661,7 @@ pub fn sprintf(_format: &str, _args: &[PhpMixed]) -> String { i += 1; } if i > start { - width = _format[start..i].parse().unwrap_or(0); + width = format[start..i].parse().unwrap_or(0); } } @@ -673,7 +673,7 @@ pub fn sprintf(_format: &str, _args: &[PhpMixed]) -> String { while i < fb.len() && fb[i].is_ascii_digit() { i += 1; } - precision = Some(_format[start..i].parse().unwrap_or(0)); + precision = Some(format[start..i].parse().unwrap_or(0)); } if i >= fb.len() { @@ -683,9 +683,9 @@ pub fn sprintf(_format: &str, _args: &[PhpMixed]) -> String { i += 1; let arg = match explicit_arg { - Some(n) => _args.get(n.wrapping_sub(1)), + Some(n) => args.get(n.wrapping_sub(1)), None => { - let a = _args.get(next_arg); + let a = args.get(next_arg); next_arg += 1; a } @@ -841,8 +841,8 @@ fn php_to_float(v: &PhpMixed) -> f64 { } } -pub fn bin2hex(_data: &[u8]) -> String { - _data.iter().map(|b| format!("{:02x}", b)).collect() +pub fn bin2hex(data: &[u8]) -> String { + data.iter().map(|b| format!("{:02x}", b)).collect() } pub fn ucfirst(s: &str) -> String { @@ -989,11 +989,11 @@ pub fn php_strip_whitespace(path: impl AsRef<std::path::Path>) -> Result<String, Ok(String::from_utf8_lossy(&out).into_owned()) } -pub fn hexdec(_s: &str) -> i64 { +pub fn hexdec(s: &str) -> i64 { // PHP hexdec() ignores characters outside [0-9A-Fa-f]. // TODO(phase-c): PHP promotes the result to float on overflow; this i64 return wraps instead. let mut acc: u64 = 0; - for &b in _s.as_bytes() { + for &b in s.as_bytes() { let d = match b { b'0'..=b'9' => b - b'0', b'a'..=b'f' => b - b'a' + 10, @@ -1009,17 +1009,17 @@ pub fn byte_at(s: &str, i: usize) -> u8 { s.as_bytes().get(i).copied().unwrap_or(0) } -pub fn wordwrap(_s: &str, _width: i64, _break_str: &str, _cut: bool) -> String { +pub fn wordwrap(s: &str, width: i64, break_str: &str, cut: bool) -> String { // PHP throws a ValueError for either argument combination before reaching the wrapping loop. assert!( - !_break_str.is_empty(), + !break_str.is_empty(), "wordwrap(): Argument #3 ($break) must not be empty" ); assert!( - !(_width == 0 && _cut), + !(width == 0 && cut), "wordwrap(): Argument #4 ($cut) cannot be true when argument #2 ($width) is 0" ); - php_wordwrap(_s, _width, _break_str, _cut) + php_wordwrap(s, width, break_str, cut) } pub fn levenshtein(string1: &str, string2: &str) -> i64 { @@ -1041,14 +1041,14 @@ pub fn levenshtein(string1: &str, string2: &str) -> i64 { } pub fn number_format( - _number: f64, - _decimals: i64, - _decimal_separator: &str, - _thousands_separator: &str, + number: f64, + decimals: i64, + decimal_separator: &str, + thousands_separator: &str, ) -> String { - let decimals = _decimals.max(0) as usize; - let negative = _number < 0.0; - let magnitude = _number.abs(); + let decimals = decimals.max(0) as usize; + let negative = number < 0.0; + let magnitude = number.abs(); // PHP rounds half away from zero; Rust's f64::round() does the same, so round the scaled value // to a whole number before formatting to avoid the round-half-to-even of `{:.*}`. let factor = 10f64.powi(decimals as i32); @@ -1066,12 +1066,12 @@ pub fn number_format( let len = int_bytes.len(); for (idx, &b) in int_bytes.iter().enumerate() { if idx > 0 && (len - idx) % 3 == 0 { - result.push_str(_thousands_separator); + result.push_str(thousands_separator); } result.push(b as char); } if decimals > 0 { - result.push_str(_decimal_separator); + result.push_str(decimal_separator); result.push_str(frac_part); } // PHP drops the sign when the rounded value is zero. @@ -1081,19 +1081,14 @@ pub fn number_format( result } -pub fn uniqid(_prefix: &str, _more_entropy: bool) -> String { +pub fn uniqid(prefix: &str, more_entropy: bool) -> String { // PHP builds the id from the current time: 8 hex digits of seconds followed by 5 hex digits of // microseconds. With $more_entropy a '.' and a random fraction (PHP's "%08.8F") are appended. let now = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default(); - let base = format!( - "{}{:08x}{:05x}", - _prefix, - now.as_secs(), - now.subsec_micros() - ); - if _more_entropy { + let base = format!("{}{:08x}{:05x}", prefix, now.as_secs(), now.subsec_micros()); + if more_entropy { // TODO(phase-c): PHP uses its combined LCG; this uses `fastrand`, so the random suffix is // not reproducible against PHP (it is non-deterministic in PHP too). format!("{}.{:.8}", base, fastrand::f64() * 10.0) diff --git a/crates/shirabe-php-shim/src/var.rs b/crates/shirabe-php-shim/src/var.rs index af3c1b3b..bf8fa0ce 100644 --- a/crates/shirabe-php-shim/src/var.rs +++ b/crates/shirabe-php-shim/src/var.rs @@ -93,21 +93,21 @@ pub fn canonical_int_key(key: &str) -> Option<i64> { key.parse::<i64>().ok() } -pub fn is_bool(_value: &PhpMixed) -> bool { - matches!(_value, PhpMixed::Bool(_)) +pub fn is_bool(value: &PhpMixed) -> bool { + matches!(value, PhpMixed::Bool(_)) } -pub fn is_string(_value: &PhpMixed) -> bool { - matches!(_value, PhpMixed::String(_)) +pub fn is_string(value: &PhpMixed) -> bool { + matches!(value, PhpMixed::String(_)) } -pub fn is_int(_value: &PhpMixed) -> bool { - matches!(_value, PhpMixed::Int(_)) +pub fn is_int(value: &PhpMixed) -> bool { + matches!(value, PhpMixed::Int(_)) } -pub fn is_scalar(_value: &PhpMixed) -> bool { +pub fn is_scalar(value: &PhpMixed) -> bool { matches!( - _value, + value, PhpMixed::Bool(_) | PhpMixed::Int(_) | PhpMixed::Float(_) | PhpMixed::String(_) ) } @@ -131,8 +131,8 @@ pub fn is_callable(value: &PhpMixed) -> bool { } } -pub fn is_object(_value: &PhpMixed) -> bool { - matches!(_value, PhpMixed::Object(_)) +pub fn is_object(value: &PhpMixed) -> bool { + matches!(value, PhpMixed::Object(_)) } pub fn is_a(_object_or_class: &PhpMixed, _class: &str, _allow_string: bool) -> bool { @@ -141,12 +141,12 @@ pub fn is_a(_object_or_class: &PhpMixed, _class: &str, _allow_string: bool) -> b todo!() } -pub fn is_array(_value: &PhpMixed) -> bool { - matches!(_value, PhpMixed::List(_) | PhpMixed::Array(_)) +pub fn is_array(value: &PhpMixed) -> bool { + matches!(value, PhpMixed::List(_) | PhpMixed::Array(_)) } -pub fn is_null(_value: &PhpMixed) -> bool { - matches!(_value, PhpMixed::Null) +pub fn is_null(value: &PhpMixed) -> bool { + matches!(value, PhpMixed::Null) } pub fn is_iterable(value: &PhpMixed) -> bool { @@ -255,9 +255,9 @@ pub fn strval(value: &PhpMixed) -> String { php_to_string(value) } -pub fn intval(_value: &PhpMixed) -> i64 { +pub fn intval(value: &PhpMixed) -> i64 { // Single-argument PHP intval(), i.e. base 10. - match _value { + match value { PhpMixed::Null => 0, PhpMixed::Bool(b) => *b as i64, PhpMixed::Int(i) => *i, |
