Skip to content

Commit f37ef6f

Browse files
committed
Removed unnecessary QuotedString from SExpr model
1 parent e751355 commit f37ef6f

File tree

4 files changed

+73
-94
lines changed

4 files changed

+73
-94
lines changed

snx-rs-gui/src/settings.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ impl SettingsDialog {
348348
.map(|factor| factor.factor_type.clone())
349349
.collect::<Vec<_>>();
350350
unsafe { auth_type.set_data(&option.id, factors); }
351-
auth_type.append(Some(&option.id), &option.display_name.0);
351+
auth_type.append(Some(&option.id), &option.display_name);
352352
if params2.login_type == option.id {
353353
auth_type.set_active(Some(i as _));
354354
}

snxcore/src/model/proto.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ pub struct OfficeMode {
9393
pub ipaddr: String,
9494
pub keep_address: Option<bool>,
9595
pub dns_servers: Option<Vec<Ipv4Addr>>,
96-
pub dns_suffix: Option<QuotedStringList>,
96+
pub dns_suffix: Option<StringList>,
9797
}
9898

9999
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -220,16 +220,16 @@ pub struct MultiChallengeRequest {
220220

221221
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
222222
pub struct ClientLoggingData {
223-
pub client_name: Option<QuotedString>,
223+
pub client_name: Option<String>,
224224
pub client_ver: Option<String>,
225225
pub client_build_number: Option<String>,
226226
pub os_name: Option<String>,
227227
pub os_version: Option<String>,
228228
pub device_type: Option<String>,
229229
pub hardware_model: Option<String>,
230230
pub machine_name: Option<String>,
231-
pub device_id: Option<QuotedString>,
232-
pub mac_address: Option<QuotedStringList>,
231+
pub device_id: Option<String>,
232+
pub mac_address: Option<StringList>,
233233
pub physical_ip: Option<Ipv4Addr>,
234234
pub is_compliant: Option<String>,
235235
}
@@ -324,7 +324,7 @@ pub struct KeyManagementResponse {
324324
pub om_dns0: Option<u32>,
325325
pub om_dns1: Option<u32>,
326326
pub om_dns2: Option<u32>,
327-
pub om_domain_name: Option<QuotedString>,
327+
pub om_domain_name: Option<String>,
328328
pub lifetime: Option<u64>,
329329
pub encalg: EncryptionAlgorithm,
330330
pub authalg: AuthenticationAlgorithm,
@@ -380,7 +380,7 @@ pub struct DisconnectRequest {
380380
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
381381
pub struct DisconnectRequestData {
382382
pub code: String,
383-
pub message: Option<QuotedString>,
383+
pub message: Option<String>,
384384
}
385385

386386
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
@@ -406,7 +406,7 @@ pub struct ProtocolVersion {
406406
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
407407
pub struct UpgradeConfiguration {
408408
pub available_client_version: u32,
409-
pub client_upgrade_url: QuotedString,
409+
pub client_upgrade_url: String,
410410
pub upgrade_mode: String,
411411
}
412412

@@ -420,7 +420,7 @@ pub struct ConnectivityInfo {
420420
pub ipsec_transport: String,
421421
pub tcpt_port: u16,
422422
pub natt_port: u16,
423-
pub connect_with_certificate_url: QuotedString,
423+
pub connect_with_certificate_url: String,
424424
pub cookie_name: String,
425425
pub internal_ca_fingerprint: BTreeMap<String, String>,
426426
}
@@ -435,7 +435,7 @@ pub struct LoginOptionsData {
435435
pub struct LoginOption {
436436
pub id: String,
437437
pub secondary_realm_hash: String,
438-
pub display_name: QuotedString,
438+
pub display_name: String,
439439
pub show_realm: u32,
440440
pub factors: BTreeMap<String, LoginFactor>,
441441
}
@@ -463,15 +463,15 @@ pub struct LoginFactor {
463463
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
464464
#[serde(untagged)]
465465
pub enum LoginDisplayLabelSelect {
466-
LoginDisplayLabel(BTreeMap<String, QuotedString>),
466+
LoginDisplayLabel(BTreeMap<String, String>),
467467
Empty(String),
468468
}
469469

470470
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
471471
pub struct LoginDisplayLabel {
472-
pub header: QuotedString,
473-
pub username: Option<QuotedString>,
474-
pub password: Option<QuotedString>,
472+
pub header: String,
473+
pub username: Option<String>,
474+
pub password: Option<String>,
475475
}
476476

477477
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]

snxcore/src/model/wrappers.rs

+9-61
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,11 @@ use serde::{
55
Deserialize, Deserializer, Serialize, Serializer,
66
};
77

8-
/// String encoded with double quotes
8+
/// String separated with commas or semicolons
99
#[derive(Default, Clone, PartialEq)]
10-
pub struct QuotedString(pub String);
10+
pub struct StringList(pub Vec<String>);
1111

12-
impl Serialize for QuotedString {
13-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
14-
where
15-
S: Serializer,
16-
{
17-
format!("\"{}\"", self.0).serialize(serializer)
18-
}
19-
}
20-
21-
impl<'de> Deserialize<'de> for QuotedString {
22-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
23-
where
24-
D: Deserializer<'de>,
25-
{
26-
Ok(Self(String::deserialize(deserializer)?.trim_matches('"').to_owned()))
27-
}
28-
}
29-
30-
impl From<String> for QuotedString {
31-
fn from(value: String) -> Self {
32-
Self(value)
33-
}
34-
}
35-
36-
impl From<QuotedString> for String {
37-
fn from(value: QuotedString) -> Self {
38-
value.0
39-
}
40-
}
41-
42-
impl<'a> From<&'a str> for QuotedString {
43-
fn from(value: &'a str) -> Self {
44-
Self(value.to_owned())
45-
}
46-
}
47-
48-
impl fmt::Display for QuotedString {
49-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50-
std::fmt::Display::fmt(&self.0, f)
51-
}
52-
}
53-
54-
impl fmt::Debug for QuotedString {
55-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56-
std::fmt::Debug::fmt(&self.0, f)
57-
}
58-
}
59-
60-
/// String encoded with double quotes and separated with commas
61-
#[derive(Default, Clone, PartialEq)]
62-
pub struct QuotedStringList(pub Vec<String>);
63-
64-
impl Serialize for QuotedStringList {
12+
impl Serialize for StringList {
6513
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
6614
where
6715
S: Serializer,
@@ -70,7 +18,7 @@ impl Serialize for QuotedStringList {
7018
}
7119
}
7220

73-
impl<'de> Deserialize<'de> for QuotedStringList {
21+
impl<'de> Deserialize<'de> for StringList {
7422
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
7523
where
7624
D: Deserializer<'de>,
@@ -85,19 +33,19 @@ impl<'de> Deserialize<'de> for QuotedStringList {
8533
}
8634
}
8735

88-
impl From<Vec<String>> for QuotedStringList {
36+
impl From<Vec<String>> for StringList {
8937
fn from(value: Vec<String>) -> Self {
9038
Self(value)
9139
}
9240
}
9341

94-
impl From<QuotedStringList> for Vec<String> {
95-
fn from(value: QuotedStringList) -> Self {
42+
impl From<StringList> for Vec<String> {
43+
fn from(value: StringList) -> Self {
9644
value.0
9745
}
9846
}
9947

100-
impl fmt::Debug for QuotedStringList {
48+
impl fmt::Debug for StringList {
10149
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10250
std::fmt::Debug::fmt(&self.0, f)
10351
}
@@ -122,7 +70,7 @@ impl<'de> Deserialize<'de> for EncryptedString {
12270
D: Deserializer<'de>,
12371
{
12472
let s = String::deserialize(deserializer)?;
125-
let decrypted = crate::util::snx_decrypt(s.as_bytes()).map_err(serde::de::Error::custom)?;
73+
let decrypted = crate::util::snx_decrypt(s.as_bytes()).map_err(Error::custom)?;
12674
Ok(Self(String::from_utf8_lossy(&decrypted).into_owned()))
12775
}
12876
}

snxcore/src/sexpr.rs

+50-19
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ struct SExpressionParser;
1717
pub enum SExpression {
1818
Null,
1919
Value(String),
20-
QuotedValue(String),
2120
Object(Option<String>, BTreeMap<String, SExpression>),
2221
Array(Vec<SExpression>),
2322
}
@@ -40,9 +39,7 @@ impl SExpression {
4039
}
4140

4241
pub fn get_value<T: FromStr>(&self, path: &str) -> Option<T> {
43-
self.get(path)
44-
.and_then(|v| v.as_value().or_else(|| v.as_quoted_value()))
45-
.and_then(|v| v.parse().ok())
42+
self.get(path).and_then(|v| v.as_value()).and_then(|v| v.parse().ok())
4643
}
4744

4845
pub fn get_num_value<T: Num>(&self, path: &str) -> Option<T> {
@@ -89,8 +86,7 @@ impl SExpression {
8986
fn encode_with_level(&self, level: u32) -> Option<String> {
9087
match self {
9188
SExpression::Null => None,
92-
SExpression::Value(value) => Some(format!("({value})")),
93-
SExpression::QuotedValue(value) => Some(format!("(\"{value}\")")),
89+
SExpression::Value(value) => Some(format_value(value)),
9490
SExpression::Object(name, object) => Some(self.encode_object(level, name.as_deref(), object)),
9591
SExpression::Array(items) => Some(self.encode_array(level, items)),
9692
}
@@ -130,7 +126,6 @@ impl SExpression {
130126
match self {
131127
Self::Null => Value::Null,
132128
Self::Value(v) => to_json_value(v),
133-
Self::QuotedValue(v) => Value::String(format!("\"{v}\"")),
134129
Self::Object(name, fields) => to_json_object(name.as_deref(), fields),
135130
SExpression::Array(elements) => Value::Array(elements.iter().map(|v| v.to_json()).collect()),
136131
}
@@ -141,13 +136,7 @@ impl SExpression {
141136
Value::Null => Self::Null,
142137
Value::Bool(v) => Self::Value(v.to_string()),
143138
Value::Number(v) => Self::Value(v.to_string()),
144-
Value::String(v) => {
145-
if v.starts_with('"') && v.ends_with('"') {
146-
Self::QuotedValue(v.trim_matches('"').to_string())
147-
} else {
148-
Self::Value(v.to_string())
149-
}
150-
}
139+
Value::String(v) => Self::Value(v.to_string()),
151140
Value::Array(v) => Self::Array(v.into_iter().map(Self::from_json).collect()),
152141
Value::Object(v) => match v.iter().next() {
153142
Some((key, value)) if key.starts_with('(') => Self::Object(
@@ -211,6 +200,14 @@ fn to_json_value(v: &str) -> Value {
211200
}
212201
}
213202

203+
fn format_value(value: &str) -> String {
204+
if value.contains(|c: char| !c.is_alphanumeric()) {
205+
format!("(\"{}\")", value)
206+
} else {
207+
format!("({})", value)
208+
}
209+
}
210+
214211
fn to_json_object<N: AsRef<str>, K: AsRef<str>>(name: Option<N>, fields: &BTreeMap<K, SExpression>) -> Value {
215212
let inner = Value::Object(
216213
fields
@@ -277,7 +274,7 @@ fn parse_value(mut pairs: RulePairs) -> anyhow::Result<SExpression> {
277274
match pairs.next() {
278275
Some(pair) if pair.as_rule() == Rule::quoted_str => {
279276
let value = pair.into_inner().as_str().to_owned();
280-
Ok(SExpression::QuotedValue(value))
277+
Ok(SExpression::Value(value))
281278
}
282279
Some(pair) if pair.as_rule() == Rule::simple_val => {
283280
let value = pair.as_str().to_owned();
@@ -356,8 +353,13 @@ mod tests {
356353
fn test_parse_array() {
357354
let data = "(Response :data (: (hello) : (world)))";
358355
let expr = data.parse::<SExpression>().unwrap();
359-
println!("{expr:#?}");
360-
println!("{expr}");
356+
assert_eq!(
357+
expr.get("Response:data").unwrap().as_array().unwrap(),
358+
&vec![
359+
SExpression::Value("hello".to_string()),
360+
SExpression::Value("world".to_string())
361+
]
362+
);
361363
}
362364

363365
#[test]
@@ -368,7 +370,36 @@ mod tests {
368370
}
369371
let data = Data { key: None };
370372
let expr = SExpression::from(&data);
371-
println!("{expr:#?}");
372-
println!("{expr}");
373+
assert_eq!(expr.get("key"), Some(&SExpression::Null));
374+
}
375+
376+
#[test]
377+
fn test_quoted_value_from_str() {
378+
let data = "(Response\n\t:data (\"hello world\"))";
379+
let expr = data.parse::<SExpression>().unwrap();
380+
381+
let inner = expr.get("Response:data").unwrap().as_value().unwrap();
382+
assert_eq!(inner, "hello world");
383+
384+
let encoded = format!("{}", expr);
385+
assert_eq!(encoded, data);
386+
}
387+
388+
#[test]
389+
fn test_quoted_value_from_pod() {
390+
#[derive(Serialize)]
391+
struct Data {
392+
key: String,
393+
}
394+
let data = Data {
395+
key: "Helloworld!".to_owned(),
396+
};
397+
let expr = SExpression::from(&data);
398+
399+
let inner = expr.get("key").unwrap().as_value().unwrap();
400+
assert_eq!(inner, "Helloworld!");
401+
402+
let encoded = format!("{}", expr);
403+
assert_eq!(encoded, "(\n\t:key (\"Helloworld!\"))");
373404
}
374405
}

0 commit comments

Comments
 (0)