@@ -189,12 +189,19 @@ impl ZendHashTable {
189189 /// assert_eq!(ht.get("test").and_then(|zv| zv.str()), Some("hello world"));
190190 /// ```
191191 #[ must_use]
192- pub fn get < ' a , K > ( & self , key : K ) -> Option < & Zval > where K : Into < ArrayKeyRef < ' a > > {
192+ pub fn get < ' a , K > ( & self , key : K ) -> Option < & Zval > where K : Into < ArrayKey < ' a > > {
193193 match key. into ( ) {
194- ArrayKeyRef :: Long ( index) => {
194+ ArrayKey :: Long ( index) => {
195195 unsafe { zend_hash_index_find ( self , index as zend_ulong ) . as_ref ( ) }
196196 }
197- ArrayKeyRef :: String ( key) => {
197+ ArrayKey :: String ( key) => {
198+ if let Ok ( index) = i64:: from_str ( key. as_str ( ) ) {
199+ unsafe { zend_hash_index_find ( self , index as zend_ulong ) . as_ref ( ) }
200+ } else {
201+ unsafe { zend_hash_str_find ( self , CString :: new ( key. as_str ( ) ) . ok ( ) ?. as_ptr ( ) , key. len ( ) as _ ) . as_ref ( ) }
202+ }
203+ }
204+ ArrayKey :: Str ( key) => {
198205 if let Ok ( index) = i64:: from_str ( key) {
199206 unsafe { zend_hash_index_find ( self , index as zend_ulong ) . as_ref ( ) }
200207 } else {
@@ -310,12 +317,19 @@ impl ZendHashTable {
310317 /// ht.remove("test");
311318 /// assert_eq!(ht.len(), 0);
312319 /// ```
313- pub fn remove < ' a , K > ( & mut self , key : K ) -> Option < ( ) > where K : Into < ArrayKeyRef < ' a > > {
320+ pub fn remove < ' a , K > ( & mut self , key : K ) -> Option < ( ) > where K : Into < ArrayKey < ' a > > {
314321 let result = match key. into ( ) {
315- ArrayKeyRef :: Long ( index) => {
322+ ArrayKey :: Long ( index) => {
316323 unsafe { zend_hash_index_del ( self , index as zend_ulong ) }
317324 }
318- ArrayKeyRef :: String ( key) => {
325+ ArrayKey :: String ( key) => {
326+ if let Ok ( index) = i64:: from_str ( key. as_str ( ) ) {
327+ unsafe { zend_hash_index_del ( self , index as zend_ulong ) }
328+ } else {
329+ unsafe { zend_hash_str_del ( self , CString :: new ( key. as_str ( ) ) . ok ( ) ?. as_ptr ( ) , key. len ( ) as _ ) }
330+ }
331+ }
332+ ArrayKey :: Str ( key) => {
319333 if let Ok ( index) = i64:: from_str ( key) {
320334 unsafe { zend_hash_index_del ( self , index as zend_ulong ) }
321335 } else {
@@ -396,15 +410,22 @@ impl ZendHashTable {
396410 /// ```
397411 pub fn insert < ' a , K , V > ( & mut self , key : K , val : V ) -> Result < ( ) >
398412 where
399- K : Into < ArrayKeyRef < ' a > > ,
413+ K : Into < ArrayKey < ' a > > ,
400414 V : IntoZval ,
401415 {
402416 let mut val = val. into_zval ( false ) ?;
403417 match key. into ( ) {
404- ArrayKeyRef :: Long ( index) => {
418+ ArrayKey :: Long ( index) => {
405419 unsafe { zend_hash_index_update ( self , index as zend_ulong , & mut val) } ;
406420 }
407- ArrayKeyRef :: String ( key) => {
421+ ArrayKey :: String ( key) => {
422+ if let Ok ( idx) = i64:: from_str ( & key) {
423+ unsafe { zend_hash_index_update ( self , idx as zend_ulong , & mut val) } ;
424+ } else {
425+ unsafe { zend_hash_str_update ( self , CString :: new ( key. as_str ( ) ) ?. as_ptr ( ) , key. len ( ) , & mut val) } ;
426+ }
427+ }
428+ ArrayKey :: Str ( key) => {
408429 if let Ok ( idx) = i64:: from_str ( key) {
409430 unsafe { zend_hash_index_update ( self , idx as zend_ulong , & mut val) } ;
410431 } else {
@@ -640,39 +661,15 @@ pub struct Iter<'a> {
640661
641662/// Represents the key of a PHP array, which can be either a long or a string.
642663#[ derive( Debug , PartialEq ) ]
643- pub enum ArrayKey {
664+ pub enum ArrayKey < ' a > {
644665 /// A numerical key.
645666 Long ( i64 ) ,
646667 /// A string key.
647668 String ( String ) ,
669+ Str ( & ' a str ) ,
648670}
649671
650-
651- /// Represents the key of a PHP array, which can be either a long or a string.
652- #[ derive( Debug , PartialEq ) ]
653- pub enum ArrayKeyRef < ' a > {
654- /// A numerical key.
655- Long ( i64 ) ,
656- /// A string key.
657- String ( & ' a str ) ,
658- }
659-
660- impl ArrayKeyRef < ' _ > {
661- /// Check if the key is an integer.
662- ///
663- /// # Returns
664- ///
665- /// Returns true if the key is an integer, false otherwise.
666- #[ must_use]
667- pub fn is_long ( & self ) -> bool {
668- match self {
669- ArrayKeyRef :: Long ( _) => true ,
670- ArrayKeyRef :: String ( _) => false ,
671- }
672- }
673- }
674-
675- impl ArrayKey {
672+ impl ArrayKey < ' _ > {
676673 /// Check if the key is an integer.
677674 ///
678675 /// # Returns
@@ -683,29 +680,34 @@ impl ArrayKey {
683680 match self {
684681 ArrayKey :: Long ( _) => true ,
685682 ArrayKey :: String ( _) => false ,
683+ ArrayKey :: Str ( _) => false ,
686684 }
687685 }
688686}
689687
690- impl Display for ArrayKey {
688+ impl Display for ArrayKey < ' _ > {
691689 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
692690 match self {
693691 ArrayKey :: Long ( key) => write ! ( f, "{key}" ) ,
694692 ArrayKey :: String ( key) => write ! ( f, "{key}" ) ,
693+ ArrayKey :: Str ( key) => write ! ( f, "{key}" ) ,
695694 }
696695 }
697696}
698697
699- impl Display for ArrayKeyRef < ' _ > {
700- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
701- match self {
702- ArrayKeyRef :: Long ( key) => write ! ( f, "{key}" ) ,
703- ArrayKeyRef :: String ( key) => write ! ( f, "{key}" ) ,
704- }
698+ impl < ' a > From < & ' a str > for ArrayKey < ' a > {
699+ fn from ( key : & ' a str ) -> ArrayKey < ' a > {
700+ ArrayKey :: Str ( key)
701+ }
702+ }
703+
704+ impl < ' a > From < i64 > for ArrayKey < ' a > {
705+ fn from ( index : i64 ) -> ArrayKey < ' a > {
706+ ArrayKey :: Long ( index)
705707 }
706708}
707709
708- impl < ' a > FromZval < ' a > for ArrayKey {
710+ impl < ' a > FromZval < ' a > for ArrayKey < ' _ > {
709711 const TYPE : DataType = DataType :: String ;
710712
711713 fn from_zval ( zval : & ' a Zval ) -> Option < Self > {
@@ -719,32 +721,6 @@ impl<'a> FromZval<'a> for ArrayKey {
719721 }
720722}
721723
722- impl < ' a > FromZval < ' a > for ArrayKeyRef < ' a > {
723- const TYPE : DataType = DataType :: String ;
724-
725- fn from_zval ( zval : & ' a Zval ) -> Option < ArrayKeyRef < ' a > > {
726- if let Some ( key) = zval. long ( ) {
727- return Some ( ArrayKeyRef :: Long ( key) ) ;
728- }
729- if let Some ( key) = zval. str ( ) {
730- return Some ( ArrayKeyRef :: String ( key) ) ;
731- }
732- None
733- }
734- }
735-
736- impl < ' a > From < & ' a str > for ArrayKeyRef < ' a > {
737- fn from ( key : & ' a str ) -> ArrayKeyRef < ' a > {
738- ArrayKeyRef :: String ( key)
739- }
740- }
741-
742- impl < ' a > From < i64 > for ArrayKeyRef < ' a > {
743- fn from ( index : i64 ) -> ArrayKeyRef < ' a > {
744- ArrayKeyRef :: Long ( index)
745- }
746- }
747-
748724impl < ' a > Iter < ' a > {
749725 /// Creates a new iterator over a hashtable.
750726 ///
@@ -773,7 +749,7 @@ impl<'a> Iter<'a> {
773749}
774750
775751impl < ' a > IntoIterator for & ' a ZendHashTable {
776- type Item = ( ArrayKey , & ' a Zval ) ;
752+ type Item = ( ArrayKey < ' a > , & ' a Zval ) ;
777753 type IntoIter = Iter < ' a > ;
778754
779755 /// Returns an iterator over the key(s) and value contained inside the
@@ -800,7 +776,7 @@ impl<'a> IntoIterator for &'a ZendHashTable {
800776}
801777
802778impl < ' a > Iterator for Iter < ' a > {
803- type Item = ( ArrayKey , & ' a Zval ) ;
779+ type Item = ( ArrayKey < ' a > , & ' a Zval ) ;
804780
805781 fn next ( & mut self ) -> Option < Self :: Item > {
806782 self . next_zval ( )
0 commit comments