Browse Source

Implement String.prototype.{padStart(), padEnd()} (#56)

* Implement String.prototype.{padStart(), padEnd()}

* Fix formatting
pull/70/head
Callum Ward 5 years ago committed by Jason Williams
parent
commit
0885e0018b
  1. 82
      src/lib/js/string.rs

82
src/lib/js/string.rs

@ -340,6 +340,86 @@ pub fn last_index_of(this: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(highest_index))
}
/// Abstract method StringPad
/// Performs the actual string padding for padStart/End.
/// https://tc39.es/ecma262/#sec-stringpad
fn string_pad(
primitive: String,
max_length: i32,
fill_string: Option<String>,
at_start: bool,
) -> ResultValue {
let primitive_length = primitive.len() as i32;
if max_length <= primitive_length {
return Ok(to_value(primitive));
}
let filler = match fill_string {
Some(filler) => filler,
None => String::from(" "),
};
if filler == String::from("") {
return Ok(to_value(primitive));
}
let fill_len = max_length - primitive_length;
let mut fill_str = String::new();
while fill_str.len() < fill_len as usize {
fill_str.push_str(&filler);
}
// Cut to size max_length
let concat_fill_str: String = fill_str.chars().take(fill_len as usize).collect();
if at_start {
return Ok(to_value(concat_fill_str + &primitive));
} else {
return Ok(to_value(primitive + &concat_fill_str));
}
}
/// String.prototype.padEnd ( maxLength [ , fillString ] )
///
/// Pads the string with the given filler at the end of the string.
/// Filler defaults to single space.
/// https://tc39.es/ecma262/#sec-string.prototype.padend
pub fn pad_end(this: Value, _: Value, args: Vec<Value>) -> ResultValue {
let primitive_val: String =
from_value(this.get_private_field(String::from("PrimitiveValue"))).unwrap();
if args.len() < 1 {
return Err(to_value("padEnd requires maxLength argument"));
}
let max_length = from_value(args[0].clone()).unwrap();
let fill_string: Option<String> = match args.len() {
1 => None,
_ => Some(from_value(args[1].clone()).unwrap()),
};
string_pad(primitive_val, max_length, fill_string, false)
}
/// String.prototype.padStart ( maxLength [ , fillString ] )
///
/// Pads the string with the given filler at the start of the string.
/// Filler defaults to single space.
/// https://tc39.es/ecma262/#sec-string.prototype.padstart
pub fn pad_start(this: Value, _: Value, args: Vec<Value>) -> ResultValue {
let primitive_val: String =
from_value(this.get_private_field(String::from("PrimitiveValue"))).unwrap();
if args.len() < 1 {
return Err(to_value("padStart requires maxLength argument"));
}
let max_length = from_value(args[0].clone()).unwrap();
let fill_string: Option<String> = match args.len() {
1 => None,
_ => Some(from_value(args[1].clone()).unwrap()),
};
string_pad(primitive_val, max_length, fill_string, true)
}
fn is_trimmable_whitespace(c: char) -> bool {
// The rust implementation of `trim` does not regard the same characters whitespace as ecma standard does
//
@ -399,6 +479,8 @@ pub fn _create(global: &Value) -> Value {
proto.set_field_slice("includes", to_value(includes as NativeFunctionData));
proto.set_field_slice("indexOf", to_value(index_of as NativeFunctionData));
proto.set_field_slice("lastIndexOf", to_value(last_index_of as NativeFunctionData));
proto.set_field_slice("padEnd", to_value(pad_end as NativeFunctionData));
proto.set_field_slice("padStart", to_value(pad_start as NativeFunctionData));
proto.set_field_slice("trim", to_value(trim as NativeFunctionData));
proto.set_field_slice("trimStart", to_value(trim_start as NativeFunctionData));
string.set_field_slice(PROTOTYPE, proto);

Loading…
Cancel
Save