Skip to content

Commit a6d076e

Browse files
committed
chore(macro)!: change rename defaults to match psr
BREAKING CHANGE: Methods and Properties are renamed to camelCase by default. Classes to PascalCase and constants to UPPER_CASE. Refs: #189
1 parent e520e33 commit a6d076e

File tree

24 files changed

+144
-125
lines changed

24 files changed

+144
-125
lines changed

crates/macros/src/class.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use quote::quote;
55
use syn::{Attribute, Expr, Fields, ItemStruct};
66

77
use crate::helpers::get_docs;
8-
use crate::parsing::PhpRename;
8+
use crate::parsing::{PhpRename, RenameRule};
99
use crate::prelude::*;
1010

1111
#[derive(FromAttributes, Debug, Default)]
@@ -35,7 +35,7 @@ pub struct ClassEntryAttribute {
3535
pub fn parser(mut input: ItemStruct) -> Result<TokenStream> {
3636
let attr = StructAttributes::from_attributes(&input.attrs)?;
3737
let ident = &input.ident;
38-
let name = attr.rename.rename(ident.to_string());
38+
let name = attr.rename.rename(ident.to_string(), RenameRule::Pascal);
3939
let docs = get_docs(&attr.attrs)?;
4040
input.attrs.retain(|attr| !attr.path().is_ident("php"));
4141

@@ -107,7 +107,9 @@ struct Property<'a> {
107107

108108
impl Property<'_> {
109109
pub fn name(&self) -> String {
110-
self.attr.rename.rename(self.ident.to_string())
110+
self.attr
111+
.rename
112+
.rename(self.ident.to_string(), RenameRule::Camel)
111113
}
112114
}
113115

crates/macros/src/constant.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use quote::{format_ident, quote};
44
use syn::ItemConst;
55

66
use crate::helpers::get_docs;
7-
use crate::parsing::PhpRename;
7+
use crate::parsing::{PhpRename, RenameRule};
88
use crate::prelude::*;
99

1010
const INTERNAL_CONST_DOC_PREFIX: &str = "_internal_const_docs_";
@@ -23,7 +23,9 @@ pub(crate) struct PhpConstAttribute {
2323
pub fn parser(mut item: ItemConst) -> Result<TokenStream> {
2424
let attr = PhpConstAttribute::from_attributes(&item.attrs)?;
2525

26-
let name = attr.rename.rename(item.ident.to_string());
26+
let name = attr
27+
.rename
28+
.rename(item.ident.to_string(), RenameRule::ScreamingSnakeCase);
2729
let name_ident = format_ident!("{INTERNAL_CONST_NAME_PREFIX}{}", item.ident);
2830

2931
let docs = get_docs(&attr.attrs)?;

crates/macros/src/function.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use syn::spanned::Spanned as _;
77
use syn::{Expr, FnArg, GenericArgument, ItemFn, PatType, PathArguments, Type, TypePath};
88

99
use crate::helpers::get_docs;
10-
use crate::parsing::{PhpRename, Visibility};
10+
use crate::parsing::{PhpRename, RenameRule, Visibility};
1111
use crate::prelude::*;
1212
use crate::syn_ext::DropLifetimes;
1313

@@ -46,7 +46,9 @@ pub fn parser(mut input: ItemFn) -> Result<TokenStream> {
4646

4747
let func = Function::new(
4848
&input.sig,
49-
php_attr.rename.rename(input.sig.ident.to_string()),
49+
php_attr
50+
.rename
51+
.rename(input.sig.ident.to_string(), RenameRule::Camel),
5052
args,
5153
php_attr.optional,
5254
docs,

crates/macros/src/impl_.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use syn::{Expr, Ident, ItemImpl};
88
use crate::constant::PhpConstAttribute;
99
use crate::function::{Args, CallType, Function, MethodReceiver};
1010
use crate::helpers::get_docs;
11-
use crate::parsing::{MethodRename, PhpRename, Rename, RenameRule, Visibility};
11+
use crate::parsing::{PhpRename, RenameRule, Visibility};
1212
use crate::prelude::*;
1313

1414
/// Method types.
@@ -184,8 +184,9 @@ impl<'a> ParsedImpl<'a> {
184184
match items {
185185
syn::ImplItem::Const(c) => {
186186
let attr = PhpConstAttribute::from_attributes(&c.attrs)?;
187-
let name = c.ident.rename(self.rename_constants);
188-
let name = attr.rename.rename(name);
187+
let name = attr
188+
.rename
189+
.rename(c.ident.to_string(), self.rename_constants);
189190
let docs = get_docs(&attr.attrs)?;
190191
c.attrs.retain(|attr| !attr.path().is_ident("php"));
191192

@@ -197,8 +198,9 @@ impl<'a> ParsedImpl<'a> {
197198
}
198199
syn::ImplItem::Fn(method) => {
199200
let attr = PhpFunctionImplAttribute::from_attributes(&method.attrs)?;
200-
let name = method.sig.ident.rename_method(self.rename_methods);
201-
let name = attr.rename.rename(name);
201+
let name = attr
202+
.rename
203+
.rename_method(method.sig.ident.to_string(), self.rename_methods);
202204
let docs = get_docs(&attr.attrs)?;
203205
method.attrs.retain(|attr| !attr.path().is_ident("php"));
204206

crates/macros/src/parsing.rs

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,20 @@ pub struct PhpRename {
4646
}
4747

4848
impl PhpRename {
49-
pub fn rename(&self, name: impl AsRef<str>) -> String {
50-
self.name.as_ref().map_or_else(
51-
|| {
52-
let name = name.as_ref();
53-
self.rename
54-
.as_ref()
55-
.map_or_else(|| name.to_string(), |r| name.rename(*r))
56-
},
57-
ToString::to_string,
58-
)
49+
pub fn rename(&self, name: impl AsRef<str>, default: RenameRule) -> String {
50+
if let Some(name) = self.name.as_ref() {
51+
return name.to_string();
52+
}
53+
54+
name.as_ref().rename(self.rename.unwrap_or(default))
55+
}
56+
57+
pub fn rename_method(&self, name: impl AsRef<str>, default: RenameRule) -> String {
58+
if let Some(name) = self.name.as_ref() {
59+
return name.to_string();
60+
}
61+
62+
name.as_ref().rename_method(self.rename.unwrap_or(default))
5963
}
6064
}
6165

@@ -93,32 +97,26 @@ impl RenameRule {
9397
}
9498
}
9599

96-
impl Rename for &str {
97-
fn rename(&self, rule: RenameRule) -> String {
98-
rule.rename(self)
99-
}
100-
}
101-
102-
impl Rename for syn::Ident {
100+
impl<T> Rename for T
101+
where
102+
T: ToString,
103+
{
103104
fn rename(&self, rule: RenameRule) -> String {
104-
let s = self.to_string();
105-
rule.rename(s)
106-
}
107-
}
108-
109-
impl MethodRename for syn::Ident {
110-
fn rename_method(&self, rule: RenameRule) -> String {
111-
self.to_string().as_str().rename_method(rule)
105+
rule.rename(self.to_string())
112106
}
113107
}
114108

115-
impl MethodRename for &str {
109+
impl<T> MethodRename for T
110+
where
111+
T: ToString + Rename,
112+
{
116113
fn rename_method(&self, rule: RenameRule) -> String {
114+
let original = self.to_string();
117115
match rule {
118-
RenameRule::None => (*self).to_string(),
116+
RenameRule::None => original,
119117
_ => {
120-
if MAGIC_METHOD.contains(self) {
121-
match *self {
118+
if MAGIC_METHOD.contains(&original.as_str()) {
119+
match original.as_str() {
122120
"__to_string" => "__toString".to_string(),
123121
"__debug_info" => "__debugInfo".to_string(),
124122
"__call_static" => "__callStatic".to_string(),
@@ -144,33 +142,33 @@ mod tests {
144142
name: Some("test".to_string()),
145143
rename: None,
146144
};
147-
assert_eq!(rename.rename("test"), "test");
148-
assert_eq!(rename.rename("Test"), "test");
149-
assert_eq!(rename.rename("TEST"), "test");
145+
assert_eq!(rename.rename("test", RenameRule::None), "test");
146+
assert_eq!(rename.rename("Test", RenameRule::None), "test");
147+
assert_eq!(rename.rename("TEST", RenameRule::None), "test");
150148

151149
let rename = PhpRename {
152150
name: None,
153151
rename: Some(RenameRule::ScreamingSnakeCase),
154152
};
155-
assert_eq!(rename.rename("test"), "TEST");
156-
assert_eq!(rename.rename("Test"), "TEST");
157-
assert_eq!(rename.rename("TEST"), "TEST");
153+
assert_eq!(rename.rename("test", RenameRule::None), "TEST");
154+
assert_eq!(rename.rename("Test", RenameRule::None), "TEST");
155+
assert_eq!(rename.rename("TEST", RenameRule::None), "TEST");
158156

159157
let rename = PhpRename {
160158
name: Some("test".to_string()),
161159
rename: Some(RenameRule::ScreamingSnakeCase),
162160
};
163-
assert_eq!(rename.rename("test"), "test");
164-
assert_eq!(rename.rename("Test"), "test");
165-
assert_eq!(rename.rename("TEST"), "test");
161+
assert_eq!(rename.rename("test", RenameRule::None), "test");
162+
assert_eq!(rename.rename("Test", RenameRule::None), "test");
163+
assert_eq!(rename.rename("TEST", RenameRule::None), "test");
166164

167165
let rename = PhpRename {
168166
name: None,
169167
rename: None,
170168
};
171-
assert_eq!(rename.rename("test"), "test");
172-
assert_eq!(rename.rename("Test"), "Test");
173-
assert_eq!(rename.rename("TEST"), "TEST");
169+
assert_eq!(rename.rename("test", RenameRule::None), "test");
170+
assert_eq!(rename.rename("Test", RenameRule::None), "Test");
171+
assert_eq!(rename.rename("TEST", RenameRule::None), "TEST");
174172
}
175173

176174
#[test]

guide/src/migration-guides/v0.14.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,18 @@ the following variants are equivalent:
204204
#[php(rename = case, vis = "public")]
205205
```
206206

207+
### Renaming and Case Changes
208+
209+
Default case was adjusted to match PSR standards:
210+
- Class names are now `PascalCase`
211+
- Property names are now `camelCase`
212+
- Function names are now `camelCase`
213+
- Constant names are now `UPPER_CASE`
214+
215+
This can be changed using the `rename` attribute on the item.
216+
Additionally, the `rename_methods` and `rename_consts` attributes can be used
217+
to change the case of all methods and constants in a class.
218+
207219
#### `name` vs `rename`
208220

209221
Previously the (re)name parameter was used to rename items. This has been

tests/module.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn test_module() {
2727
}
2828
}
2929

30-
let result = Embed::eval("$foo = hello_world('foo');");
30+
let result = Embed::eval("$foo = helloWorld('foo');");
3131

3232
assert!(result.is_ok());
3333

tests/sapi.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn test_sapi() {
5858
assert_eq!(result, ZEND_RESULT_CODE_SUCCESS);
5959

6060
let _ = try_catch_first(|| {
61-
let result = Embed::eval("$foo = hello_world('foo');");
61+
let result = Embed::eval("$foo = helloWorld('foo');");
6262

6363
assert!(result.is_ok());
6464

tests/src/integration/array/array.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22

33
// Tests sequential arrays
4-
$array = test_array(['a', 'b', 'c', 'd']);
4+
$array = testArray(['a', 'b', 'c', 'd']);
55
unset($array[2]);
66

77
assert(is_array($array));
@@ -11,7 +11,7 @@
1111
assert(in_array('d', $array));
1212

1313
// Tests associative arrays
14-
$assoc = test_array_assoc([
14+
$assoc = testArrayAssoc([
1515
'a' => '1',
1616
'b' => '2',
1717
'c' => '3'

tests/src/integration/binary/binary.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
$bin = test_binary(pack('L*', 1, 2, 3, 4, 5));
3+
$bin = testBinary(pack('L*', 1, 2, 3, 4, 5));
44
$result = unpack('L*', $bin);
55

66
assert(count($result) === 5);

tests/src/integration/bool/bool.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
<?php
22

3-
assert(test_bool(true) === true);
4-
assert(test_bool(false) === false);
3+
assert(testBool(true) === true);
4+
assert(testBool(false) === false);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<?php
22

3-
assert(test_callable(fn (string $a) => $a, 'test') === 'test');
3+
assert(testCallable(fn (string $a) => $a, 'test') === 'test');

tests/src/integration/class/class.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require(__DIR__ . '/../_utils.php');
44

55
// Tests constructor
6-
$class = test_class('lorem ipsum', 2022);
6+
$class = testClass('lorem ipsum', 2022);
77
assert($class instanceof TestClass);
88

99
// Tests getter/setter
@@ -15,10 +15,11 @@
1515
$class->setNumber(2023);
1616
assert($class->getNumber() === 2023);
1717

18+
var_dump($class);
1819
// Tests #prop decorator
19-
assert($class->boolean);
20-
$class->boolean = false;
21-
assert($class->boolean === false);
20+
assert($class->booleanProp);
21+
$class->booleanProp = false;
22+
assert($class->booleanProp === false);
2223

2324
// Call regular from object
2425
assert($class->staticCall('Php') === 'Hello Php');
@@ -31,7 +32,7 @@
3132

3233
$ex = new TestClassExtends();
3334
assert_exception_thrown(fn() => throw $ex);
34-
assert_exception_thrown(fn() => throw_exception());
35+
assert_exception_thrown(fn() => throwException());
3536

3637
$arrayAccess = new TestClassArrayAccess();
3738
assert_exception_thrown(fn() => $arrayAccess[0] = 'foo');

tests/src/integration/class/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub struct TestClass {
66
string: String,
77
number: i32,
88
#[php(prop)]
9-
boolean: bool,
9+
boolean_prop: bool,
1010
}
1111

1212
#[php_impl]
@@ -41,7 +41,7 @@ pub fn test_class(string: String, number: i32) -> TestClass {
4141
TestClass {
4242
string,
4343
number,
44-
boolean: true,
44+
boolean_prop: true,
4545
}
4646
}
4747

tests/src/integration/closure/closure.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
require(__DIR__ . '/../_utils.php');
44

5-
$v = test_closure();
5+
$v = testClosure();
66

77
// Closure
88
assert($v('works') === 'works');
99

1010
// Closure once
11-
$closure = test_closure_once('test');
11+
$closure = testClosureOnce('test');
1212

1313
assert(call_user_func($closure) === 'test');
1414
assert_exception_thrown($closure);
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

3-
assert(test_defaults_integer() === 42);
4-
assert(test_defaults_integer(12) === 12);
5-
assert(test_defaults_nullable_string() === null);
6-
assert(test_defaults_nullable_string('test') === 'test');
3+
assert(testDefaultsInteger() === 42);
4+
assert(testDefaultsInteger(12) === 12);
5+
assert(testDefaultsNullableString() === null);
6+
assert(testDefaultsNullableString('test') === 'test');
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?php
22

3-
assert(test_globals_http_get() === []);
4-
assert(test_globals_http_post() === []);
5-
assert(test_globals_http_cookie() === []);
6-
assert(!empty(test_globals_http_server()));
7-
assert(test_globals_http_request() === []);
8-
assert(test_globals_http_files() === []);
3+
assert(testGlobalsHttpGet() === []);
4+
assert(testGlobalsHttpPost() === []);
5+
assert(testGlobalsHttpCookie() === []);
6+
assert(!empty(testGlobalsHttpServer()));
7+
assert(testGlobalsHttpRequest() === []);
8+
assert(testGlobalsHttpFiles() === []);

0 commit comments

Comments
 (0)