Skip to content

Commit eb5ccda

Browse files
committed
Add helpers for Zval coercion
1 parent e06fbaa commit eb5ccda

File tree

1 file changed

+86
-0
lines changed

1 file changed

+86
-0
lines changed

src/types/zval.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,92 @@ impl Zval {
611611
FromZval::from_zval(self)
612612
}
613613

614+
/// Coerce the value into a string. Mimics the PHP type coercion rules.
615+
pub fn coerce_into_string(&mut self) -> Result<()> {
616+
if self.is_string() {
617+
return Ok(());
618+
}
619+
620+
if let Some(val) = self.string() {
621+
self.set_string(&val, false)?;
622+
return Ok(());
623+
} else if let Some(val) = self.double() {
624+
self.set_string(&val.to_string(), false)?;
625+
return Ok(());
626+
} else if let Some(val) = self.long() {
627+
self.set_string(&val.to_string(), false)?;
628+
return Ok(());
629+
} else if let Some(val) = self.bool() {
630+
self.set_string(if val { "1" } else { "0" }, false)?;
631+
return Ok(());
632+
} else if self.is_array() {
633+
self.set_string("Array", false)?;
634+
return Ok(());
635+
}
636+
637+
Err(Error::ZvalConversion(self.get_type()))
638+
}
639+
640+
/// Coerce the value into a boolean. Mimics the PHP type coercion rules.
641+
pub fn coerce_into_bool(&mut self) -> Result<()> {
642+
if self.is_bool() {
643+
return Ok(());
644+
}
645+
646+
if let Some(val) = self.long() {
647+
self.set_bool(val != 0 );
648+
return Ok(());
649+
} else if let Some(val) = self.double() {
650+
self.set_bool(val != 0.0 );
651+
return Ok(());
652+
} else if let Some(val) = self.string() {
653+
self.set_bool(val != "0" && val != "");
654+
return Ok(());
655+
} else if let Some(val) = self.array() {
656+
self.set_bool(val.len() != 0);
657+
}
658+
659+
Err(Error::ZvalConversion(self.get_type()))
660+
}
661+
662+
/// Coerce the value into a long. Mimics the PHP type coercion rules.
663+
pub fn coerce_into_long(&mut self) -> Result<()> {
664+
if self.is_long() {
665+
return Ok(());
666+
}
667+
668+
if let Some(val) = self.double() {
669+
self.set_long(val as i64);
670+
return Ok(());
671+
} else if let Some(val) = self.string() {
672+
self.set_long(val.parse::<i64>().map_err(|_| Error::ZvalConversion(self.get_type()))?);
673+
return Ok(());
674+
} else if let Some(val) = self.array() {
675+
self.set_long(if val.len() > 0 { 1 } else { 0 });
676+
}
677+
678+
Err(Error::ZvalConversion(self.get_type()))
679+
}
680+
681+
/// Coerce the value into a double. Mimics the PHP type coercion rules.
682+
pub fn coerce_into_double(&mut self) -> Result<()> {
683+
if self.is_double() {
684+
return Ok(());
685+
}
686+
687+
if let Some(val) = self.long() {
688+
self.set_double(val as f64);
689+
return Ok(());
690+
} else if let Some(val) = self.string() {
691+
self.set_double(val.parse::<f64>().map_err(|_| Error::ZvalConversion(self.get_type()))?);
692+
return Ok(());
693+
} else if let Some(val) = self.array() {
694+
self.set_double(if val.len() > 0 { 1.0 } else { 0.0 });
695+
}
696+
697+
Err(Error::ZvalConversion(self.get_type()))
698+
}
699+
614700
/// Creates a shallow clone of the [`Zval`].
615701
///
616702
/// This copies the contents of the [`Zval`], and increments the reference

0 commit comments

Comments
 (0)