Skip to content

Commit c765a53

Browse files
authored
refactor(js): remove double wrap (#1138)
1 parent 8a92bb7 commit c765a53

File tree

6 files changed

+197
-325
lines changed

6 files changed

+197
-325
lines changed

js-rattler/crate/lib.rs

+1-27
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
mod error;
22
mod gateway;
3+
mod parse_strictness;
34
pub mod solve;
45
mod utils;
56
mod version;
67
mod version_spec;
78

89
pub use error::{JsError, JsResult};
9-
use rattler_conda_types::ParseStrictness;
1010

1111
use wasm_bindgen::prelude::*;
1212

@@ -21,29 +21,3 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
2121
pub fn start() {
2222
utils::set_panic_hook();
2323
}
24-
25-
/// Defines how strict a parser should be when parsing an object from a string.
26-
/// @public
27-
#[wasm_bindgen(js_name=ParseStrictness)]
28-
pub enum JsParseStrictness {
29-
Strict,
30-
Lenient,
31-
}
32-
33-
impl From<ParseStrictness> for JsParseStrictness {
34-
fn from(value: ParseStrictness) -> Self {
35-
match value {
36-
ParseStrictness::Strict => JsParseStrictness::Strict,
37-
ParseStrictness::Lenient => JsParseStrictness::Lenient,
38-
}
39-
}
40-
}
41-
42-
impl From<JsParseStrictness> for ParseStrictness {
43-
fn from(value: JsParseStrictness) -> Self {
44-
match value {
45-
JsParseStrictness::Strict => ParseStrictness::Strict,
46-
JsParseStrictness::Lenient => ParseStrictness::Lenient,
47-
}
48-
}
49-
}

js-rattler/crate/parse_strictness.rs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use rattler_conda_types::ParseStrictness;
2+
use serde::Deserialize;
3+
use wasm_bindgen::prelude::wasm_bindgen;
4+
5+
#[wasm_bindgen(typescript_custom_section)]
6+
const PARSE_STRICTNESS_TS: &'static str = r#"
7+
/**
8+
* Defines how strict a parser should be when parsing an object from a string.
9+
*
10+
* @public
11+
*/
12+
export type ParseStrictness = "strict" | "lenient";
13+
"#;
14+
15+
#[wasm_bindgen]
16+
extern "C" {
17+
#[wasm_bindgen(js_name = "ParseStrictness", typescript_type = "ParseStrictness")]
18+
pub type JsParseStrictness;
19+
}
20+
21+
impl TryFrom<JsParseStrictness> for ParseStrictness {
22+
type Error = serde_wasm_bindgen::Error;
23+
24+
fn try_from(value: JsParseStrictness) -> Result<Self, Self::Error> {
25+
#[derive(Deserialize)]
26+
#[serde(rename_all = "camelCase")]
27+
pub enum EnumNames {
28+
Strict,
29+
Lenient,
30+
}
31+
32+
match serde_wasm_bindgen::from_value(value.obj)? {
33+
EnumNames::Strict => Ok(ParseStrictness::Strict),
34+
EnumNames::Lenient => Ok(ParseStrictness::Lenient),
35+
}
36+
}
37+
}

js-rattler/crate/version.rs

+128-29
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
1-
use crate::JsResult;
21
use rattler_conda_types::{Version, VersionBumpType};
32
use std::{cmp::Ordering, str::FromStr};
43
use wasm_bindgen::prelude::wasm_bindgen;
4+
use wasm_bindgen::JsValue;
5+
6+
use crate::JsResult;
57

6-
#[wasm_bindgen]
8+
/// This class implements an order relation between version strings. Version
9+
/// strings can contain the usual alphanumeric characters (A-Za-z0-9), separated
10+
/// into segments by dots and underscores. Empty segments (i.e. two consecutive
11+
/// dots, a leading/trailing underscore) are not permitted. An optional epoch
12+
/// number - an integer followed by '!' - can precede the actual version string
13+
/// (this is useful to indicate a change in the versioning scheme itself).
14+
/// Version comparison is case-insensitive.
15+
///
16+
/// @public
17+
#[wasm_bindgen(js_name = "Version")]
718
#[repr(transparent)]
819
#[derive(Eq, PartialEq)]
920
pub struct JsVersion {
@@ -28,110 +39,198 @@ impl AsRef<Version> for JsVersion {
2839
}
2940
}
3041

31-
#[wasm_bindgen]
32-
pub struct MajorMinor(pub usize, pub usize);
33-
34-
#[wasm_bindgen]
42+
#[wasm_bindgen(js_class = "Version")]
3543
impl JsVersion {
44+
/// Constructs a new Version object from a string representation.
3645
#[wasm_bindgen(constructor)]
37-
pub fn new(version: &str) -> JsResult<Self> {
46+
pub fn new(
47+
#[wasm_bindgen(param_description = "The string representation of the version.")]
48+
version: &str,
49+
) -> JsResult<Self> {
3850
let version = Version::from_str(version)?;
3951
Ok(version.into())
4052
}
4153

54+
/// Returns the string representation of the version.
55+
///
56+
/// An attempt is made to return the version in the same format as the input
57+
/// string but this is not guaranteed.
58+
#[wasm_bindgen(js_name = "toString")]
4259
pub fn as_str(&self) -> String {
4360
format!("{}", self.as_ref())
4461
}
4562

63+
/// The epoch part of the version. E.g. `1` in `1!2.3`.
4664
#[wasm_bindgen(getter)]
4765
pub fn epoch(&self) -> Option<usize> {
4866
self.as_ref().epoch_opt().map(|v| v as usize)
4967
}
5068

51-
#[wasm_bindgen(getter)]
69+
/// `true` if the version has a local part. E.g. `2.3` in `1+2.3`.
70+
#[wasm_bindgen(getter, js_name = "hasLocal")]
5271
pub fn has_local(&self) -> bool {
5372
self.as_ref().has_local()
5473
}
5574

56-
#[wasm_bindgen(getter)]
75+
/// `true` if the version is considered a development version.
76+
///
77+
/// A development version is a version that contains the string `dev` in the
78+
/// version string.
79+
#[wasm_bindgen(getter, js_name = "isDev")]
5780
pub fn is_dev(&self) -> bool {
5881
self.as_ref().is_dev()
5982
}
6083

61-
pub fn as_major_minor(&self) -> Option<MajorMinor> {
84+
/// Returns the major and minor part of the version if the version does not
85+
/// represent a typical major minor version. If any of the parts are not a
86+
/// single number, undefined is returned.
87+
// TODO: Simplify when https://github.com/rustwasm/wasm-bindgen/issues/122 is fixed
88+
#[wasm_bindgen(
89+
js_name = "asMajorMinor",
90+
unchecked_return_type = "[number, number] | undefined"
91+
)]
92+
pub fn as_major_minor(&self) -> Option<Vec<JsValue>> {
6293
let (major, minor) = self.as_ref().as_major_minor()?;
63-
Some(MajorMinor(major as _, minor as _))
64-
}
65-
66-
pub fn starts_with(&self, other: &Self) -> bool {
94+
Some(vec![
95+
JsValue::from(major as usize),
96+
JsValue::from(minor as usize),
97+
])
98+
}
99+
100+
/// Returns true if this version starts with the other version. This is
101+
/// defined as the other version being a prefix of this version.
102+
#[wasm_bindgen(js_name = "startsWith")]
103+
pub fn starts_with(
104+
&self,
105+
#[wasm_bindgen(param_description = "The version to use for the comparison")] other: &Self,
106+
) -> bool {
67107
self.as_ref().starts_with(other.as_ref())
68108
}
69109

70-
pub fn compatible_with(&self, other: &Self) -> bool {
110+
/// Returns true if this version is compatible with the other version.
111+
#[wasm_bindgen(js_name = "compatibleWith")]
112+
pub fn compatible_with(
113+
&self,
114+
#[wasm_bindgen(param_description = "The version to use for the comparison")] other: &Self,
115+
) -> bool {
71116
self.as_ref().compatible_with(other.as_ref())
72117
}
73118

74-
pub fn pop_segments(&self, n: usize) -> Option<Self> {
119+
/// Pop the last `n` segments from the version.
120+
#[wasm_bindgen(js_name = "popSegments")]
121+
pub fn pop_segments(
122+
&self,
123+
#[wasm_bindgen(param_description = "The number of segments to pop")] n: usize,
124+
) -> Option<Self> {
75125
Some(self.as_ref().pop_segments(n)?.into())
76126
}
77127

78-
pub fn extend_to_length(&self, length: usize) -> JsResult<Self> {
128+
/// Extend the version to the given length by adding zeros. If the version
129+
/// is already at the specified length or longer the original version
130+
/// will be returned.
131+
#[wasm_bindgen(js_name = "extendToLength")]
132+
pub fn extend_to_length(
133+
&self,
134+
#[wasm_bindgen(param_description = "The length to extend to")] length: usize,
135+
) -> JsResult<Self> {
79136
Ok(self.as_ref().extend_to_length(length)?.into_owned().into())
80137
}
81138

82-
pub fn with_segments(&self, start: usize, stop: usize) -> Option<Self> {
83-
let range = start..stop;
139+
/// Returns a new version with the segments from start to end (exclusive).
140+
///
141+
/// Returns undefined if the start or end index is out of bounds.
142+
#[wasm_bindgen(js_name = "withSegments")]
143+
pub fn with_segments(
144+
&self,
145+
#[wasm_bindgen(param_description = "The start index")] start: usize,
146+
#[wasm_bindgen(param_description = "The end index")] end: usize,
147+
) -> Option<Self> {
148+
let range = start..end;
84149
Some(self.as_ref().with_segments(range)?.into())
85150
}
86151

152+
/// The number of segments in the version.
87153
#[wasm_bindgen(getter)]
88154
pub fn length(&self) -> usize {
89155
self.as_ref().segment_count()
90156
}
91157

92-
/// Create a new version with local segment stripped.
158+
/// Returns the version without the local part. E.g. `1+2.3` becomes `1`.
159+
#[wasm_bindgen(js_name = "stripLocal")]
93160
pub fn strip_local(&self) -> Self {
94161
self.as_ref().strip_local().into_owned().into()
95162
}
96163

97-
/// Returns a new version where the major segment of this version has been bumped.
164+
/// Returns a new version where the major segment of this version has been
165+
/// bumped.
166+
#[wasm_bindgen(js_name = "bumpMajor")]
98167
pub fn bump_major(&self) -> JsResult<Self> {
99168
Ok(self.as_ref().bump(VersionBumpType::Major).map(Into::into)?)
100169
}
101170

102-
/// Returns a new version where the minor segment of this version has been bumped.
171+
/// Returns a new version where the minor segment of this version has been
172+
/// bumped.
173+
#[wasm_bindgen(js_name = "bumpMinor")]
103174
pub fn bump_minor(&self) -> JsResult<Self> {
104175
Ok(self.as_ref().bump(VersionBumpType::Minor).map(Into::into)?)
105176
}
106177

107-
/// Returns a new version where the patch segment of this version has been bumped.
178+
/// Returns a new version where the patch segment of this version has been
179+
/// bumped.
180+
#[wasm_bindgen(js_name = "bumpPatch")]
108181
pub fn bump_patch(&self) -> JsResult<Self> {
109182
Ok(self.as_ref().bump(VersionBumpType::Patch).map(Into::into)?)
110183
}
111184

112-
/// Returns a new version where the last segment of this version has been bumped.
185+
/// Returns a new version where the last segment of this version has been
186+
/// bumped.
187+
#[wasm_bindgen(js_name = "bumpLast")]
113188
pub fn bump_last(&self) -> JsResult<Self> {
114189
Ok(self.as_ref().bump(VersionBumpType::Last).map(Into::into)?)
115190
}
116191

117-
/// Returns a new version where the given segment of this version has been bumped.
118-
pub fn bump_segment(&self, index: i32) -> JsResult<Self> {
192+
/// Returns a new version where the given segment of this version has been
193+
/// bumped.
194+
#[wasm_bindgen(js_name = "bumpSegment")]
195+
pub fn bump_segment(
196+
&self,
197+
#[wasm_bindgen(param_description = "The index of the segment to bump")] index: i32,
198+
) -> JsResult<Self> {
119199
Ok(self
120200
.as_ref()
121201
.bump(VersionBumpType::Segment(index))
122202
.map(Into::into)?)
123203
}
124204

125-
/// Returns a new version where the last segment is an "alpha" segment (ie. `.0a0`)
205+
/// Returns a new version where the last segment is an "alpha" segment (ie.
206+
/// `.0a0`)
207+
#[wasm_bindgen(js_name = "withAlpha")]
126208
pub fn with_alpha(&self) -> Self {
127209
self.as_ref().with_alpha().into_owned().into()
128210
}
129211

130-
pub fn equals(&self, other: &Self) -> bool {
212+
/// Compares this version with another version. Returns `true` if the
213+
/// versions are considered equal.
214+
///
215+
/// Note that two version strings can be considered equal even if they are
216+
/// not exactly the same. For example, `1.0` and `1` are considered equal.
217+
#[wasm_bindgen(js_name = "equals")]
218+
pub fn equals(
219+
&self,
220+
#[wasm_bindgen(param_description = "The version to compare with")] other: &Self,
221+
) -> bool {
131222
self.as_ref() == other.as_ref()
132223
}
133224

134-
pub fn compare(&self, other: &Self) -> i8 {
225+
/// Compare two versions.
226+
///
227+
/// Returns `-1` if this instance should be ordered before `other`, `0` if
228+
/// this version and `other` are considered equal, `1` if this version
229+
/// should be ordered after `other`.
230+
pub fn compare(
231+
&self,
232+
#[wasm_bindgen(param_description = "The version to compare with")] other: &Self,
233+
) -> i8 {
135234
match self.as_ref().cmp(other.as_ref()) {
136235
Ordering::Less => -1,
137236
Ordering::Equal => 0,

js-rattler/crate/version_spec.rs

+29-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
use crate::version::JsVersion;
2-
use crate::{JsParseStrictness, JsResult};
3-
use rattler_conda_types::VersionSpec;
1+
use rattler_conda_types::{ParseStrictness, VersionSpec};
42
use wasm_bindgen::prelude::wasm_bindgen;
53

6-
#[wasm_bindgen]
4+
use crate::parse_strictness::JsParseStrictness;
5+
use crate::{version::JsVersion, JsResult};
6+
7+
/// Represents a version specification in the conda ecosystem.
8+
///
9+
/// @public
10+
#[wasm_bindgen(js_name = "VersionSpec")]
711
#[repr(transparent)]
812
#[derive(Eq, PartialEq)]
913
pub struct JsVersionSpec {
@@ -28,19 +32,36 @@ impl AsRef<VersionSpec> for JsVersionSpec {
2832
}
2933
}
3034

31-
#[wasm_bindgen]
35+
#[wasm_bindgen(js_class = "VersionSpec")]
3236
impl JsVersionSpec {
37+
/// Constructs a new VersionSpec object from a string representation.
3338
#[wasm_bindgen(constructor)]
34-
pub fn new(version_spec: &str, parse_strictness: JsParseStrictness) -> JsResult<Self> {
35-
let spec = VersionSpec::from_str(version_spec, parse_strictness.into())?;
39+
pub fn new(
40+
#[wasm_bindgen(param_description = "The string representation of the version spec.")]
41+
version_spec: &str,
42+
#[wasm_bindgen(param_description = "The strictness of the parser.")]
43+
parse_strictness: Option<JsParseStrictness>,
44+
) -> JsResult<Self> {
45+
let parse_strictness = parse_strictness
46+
.map(TryFrom::try_from)
47+
.transpose()?
48+
.unwrap_or(ParseStrictness::Lenient);
49+
50+
let spec = VersionSpec::from_str(version_spec, parse_strictness)?;
3651
Ok(spec.into())
3752
}
3853

54+
/// Returns the string representation of the version spec.
55+
#[wasm_bindgen(js_name = "toString")]
3956
pub fn as_str(&self) -> String {
4057
format!("{}", self.as_ref())
4158
}
4259

43-
pub fn matches(&self, version: &JsVersion) -> bool {
60+
/// Returns true if the version matches this version spec.
61+
pub fn matches(
62+
&self,
63+
#[wasm_bindgen(param_description = "The version to match")] version: &JsVersion,
64+
) -> bool {
4465
self.as_ref().matches(version.as_ref())
4566
}
4667
}

0 commit comments

Comments
 (0)