Skip to content

Commit

Permalink
Improved Compliance of URL and URLSearchParams
Browse files Browse the repository at this point in the history
  • Loading branch information
Redfire75369 committed Jan 18, 2024
1 parent afb9318 commit 2c6f84b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 57 deletions.
2 changes: 1 addition & 1 deletion ion/src/exception.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use mozjs::jsval::{JSVal, ObjectValue};
#[cfg(feature = "sourcemap")]
use sourcemap::SourceMap;

use crate::{Context, Error, ErrorKind, Object, Stack, Result, Value};
use crate::{Context, Error, ErrorKind, Object, Result, Stack, Value};
use crate::conversions::{FromValue, ToValue};
use crate::format::{Config, format_value, NEWLINE};
use crate::stack::Location;
Expand Down
106 changes: 55 additions & 51 deletions runtime/src/globals/url/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use url::Url;

use ion::{ClassDefinition, Context, Error, Local, Object, Result};
use ion::class::Reflector;
use ion::function::{Enforce, Opt};
use ion::function::Opt;
pub use search_params::URLSearchParams;

mod search_params;
Expand Down Expand Up @@ -114,52 +114,46 @@ impl URL {
}

#[ion(get)]
pub fn get_host(&self) -> Option<String> {
self.url.host_str().map(|host| {
if let Some(port) = self.url.port() {
format!("{}:{}", host, port)
} else {
String::from(host)
}
})
pub fn get_host(&self) -> String {
self.url
.host_str()
.map(|host| {
if let Some(port) = self.url.port() {
format!("{}:{}", host, port)
} else {
String::from(host)
}
})
.unwrap_or_default()
}

#[ion(set)]
pub fn set_host(&mut self, Opt(host): Opt<String>) -> Result<()> {
if let Some(host) = host {
let segments: Vec<&str> = host.split(':').collect();
let (host, port) = match segments.len().cmp(&2) {
Ordering::Less => Ok((segments[0], None)),
Ordering::Greater => Err(Error::new("Invalid Host", None)),
Ordering::Equal => {
let port = match segments[1].parse::<u16>() {
Ok(port) => Ok(port),
Err(error) => Err(Error::new(&error.to_string(), None)),
}?;
Ok((segments[0], Some(port)))
}
}?;

self.url.set_host(Some(host))?;
pub fn set_host(&mut self, host: String) -> Result<()> {
let segments: Vec<&str> = host.split(':').collect();
let (host, port) = match segments.len().cmp(&2) {
Ordering::Less => Ok((segments[0], None)),
Ordering::Greater => Err(Error::new("Invalid Host", None)),
Ordering::Equal => {
let port = match segments[1].parse::<u16>() {
Ok(port) => Ok(port),
Err(error) => Err(Error::new(&error.to_string(), None)),
}?;
Ok((segments[0], Some(port)))
}
}?;

self.url.set_port(port).map_err(|_| Error::new("Invalid Url", None))?;
} else {
self.url.set_host(None)?;
self.url.set_port(None).map_err(|_| Error::new("Invalid Url", None))?;
}
Ok(())
self.url.set_host(Some(host))?;
self.url.set_port(port).map_err(|_| Error::new("Invalid Url", None))
}

#[ion(get)]
pub fn get_hostname(&self) -> Option<String> {
self.url.host_str().map(String::from)
pub fn get_hostname(&self) -> String {
self.url.host_str().map(String::from).unwrap_or_default()
}

#[ion(set)]
pub fn set_hostname(&mut self, Opt(hostname): Opt<String>) -> Result<()> {
self.url
.set_host(hostname.as_deref())
.map_err(|error| Error::new(&error.to_string(), None))
pub fn set_hostname(&mut self, hostname: String) -> Result<()> {
self.url.set_host(Some(&hostname)).map_err(|error| Error::new(&error.to_string(), None))
}

#[ion(get)]
Expand All @@ -168,13 +162,14 @@ impl URL {
}

#[ion(get)]
pub fn get_port(&self) -> Option<u16> {
self.url.port_or_known_default()
pub fn get_port(&self) -> String {
self.url.port_or_known_default().map(|port| port.to_string()).unwrap_or_default()
}

#[ion(set)]
pub fn set_port(&mut self, Opt(port): Opt<Enforce<u16>>) -> Result<()> {
self.url.set_port(port.map(|p| p.0)).map_err(|_| Error::new("Invalid Port", None))
pub fn set_port(&mut self, port: String) -> Result<()> {
let port = if port.is_empty() { None } else { Some(port.parse()?) };
self.url.set_port(port).map_err(|_| Error::new("Invalid Port", None))
}

#[ion(get)]
Expand Down Expand Up @@ -204,28 +199,37 @@ impl URL {
}

#[ion(set)]
pub fn set_password(&mut self, Opt(password): Opt<String>) -> Result<()> {
self.url.set_password(password.as_deref()).map_err(|_| Error::new("Invalid Url", None))
pub fn set_password(&mut self, password: String) -> Result<()> {
self.url.set_password(Some(&password)).map_err(|_| Error::new("Invalid Url", None))
}

#[ion(get)]
pub fn get_search(&self) -> Option<String> {
self.url.query().map(String::from)
pub fn get_search(&self) -> String {
self.url.query().map(|search| format!("?{}", search)).unwrap_or_default()
}

#[ion(set)]
pub fn set_search(&mut self, Opt(search): Opt<String>) {
self.url.set_query(search.as_deref());
pub fn set_search(&mut self, cx: &Context, search: String) {
if search.is_empty() {
self.url.set_query(None);
} else {
self.url.set_query(Some(&search));
}

let search_params = Object::from(unsafe { Local::from_heap(&self.search_params) });
if let Ok(search_params) = URLSearchParams::get_mut_private(cx, &search_params) {
search_params.set_pairs(self.url.query_pairs().into_owned().collect());
}
}

#[ion(get)]
pub fn get_hash(&self) -> Option<String> {
self.url.fragment().map(String::from)
pub fn get_hash(&self) -> String {
self.url.fragment().map(|hash| format!("#{}", hash)).unwrap_or_default()
}

#[ion(set)]
pub fn set_hash(&mut self, Opt(hash): Opt<String>) {
self.url.set_fragment(hash.as_deref());
pub fn set_hash(&mut self, hash: String) {
self.url.set_fragment(Some(&*hash).filter(|hash| !hash.is_empty()));
}

#[ion(get)]
Expand Down
11 changes: 6 additions & 5 deletions runtime/src/globals/url/search_params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl<'cx> FromValue<'cx> for URLSearchParamsInit {
.collect::<Result<_>>()?;
Ok(URLSearchParamsInit(vec))
} else if let Ok(string) = String::from_value(cx, value, strict, ()) {
let string = string.strip_prefix('?').unwrap_or(&string);
Ok(URLSearchParamsInit(parse(string.as_bytes()).into_owned().collect()))
} else {
Err(Error::new("Invalid Search Params Initialiser", ErrorKind::Type))
Expand All @@ -64,6 +65,10 @@ impl URLSearchParams {
pub fn pairs(&self) -> &[(String, String)] {
&self.pairs
}

pub(super) fn set_pairs(&mut self, pairs: Vec<(String, String)>) {
self.pairs = pairs;
}
}

#[js_class]
Expand All @@ -86,10 +91,6 @@ impl URLSearchParams {
}
}

pub(super) fn set_pairs(&mut self, pairs: Vec<(String, String)>) {
self.pairs = pairs;
}

#[ion(get)]
pub fn get_size(&self) -> i32 {
self.pairs.len() as i32
Expand All @@ -102,7 +103,7 @@ impl URLSearchParams {

pub fn delete(&mut self, name: String, Opt(value): Opt<String>) {
if let Some(value) = value {
self.pairs.retain(|(k, v)| k != &name && v != &value)
self.pairs.retain(|(k, v)| k != &name || v != &value)
} else {
self.pairs.retain(|(k, _)| k != &name)
}
Expand Down

0 comments on commit 2c6f84b

Please sign in to comment.