Skip to content

Commit 126d9df

Browse files
committed
extract out validation functions
1 parent 6a14ad9 commit 126d9df

File tree

1 file changed

+89
-102
lines changed
  • lazer/sdk/rust/protocol/src

1 file changed

+89
-102
lines changed

lazer/sdk/rust/protocol/src/api.rs

Lines changed: 89 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -49,40 +49,19 @@ impl<'de> Deserialize<'de> for LatestPriceRequest {
4949

5050
impl LatestPriceRequest {
5151
pub fn new(value: LatestPriceRequestRepr) -> Result<Self, &'static str> {
52-
if value.price_feed_ids.is_none() && value.symbols.is_none() {
53-
return Err("either price feed ids or symbols must be specified");
54-
}
55-
if value.price_feed_ids.is_some() && value.symbols.is_some() {
56-
return Err("either price feed ids or symbols must be specified, not both");
57-
}
58-
59-
if let Some(ref ids) = value.price_feed_ids {
60-
if ids.is_empty() {
61-
return Err("no price feed ids specified");
62-
}
63-
if !ids.iter().all_unique() {
64-
return Err("duplicate price feed ids specified");
65-
}
66-
}
67-
68-
if let Some(ref symbols) = value.symbols {
69-
if symbols.is_empty() {
70-
return Err("no symbols specified");
71-
}
72-
if !symbols.iter().all_unique() {
73-
return Err("duplicate symbols specified");
74-
}
75-
}
76-
77-
if !value.formats.iter().all_unique() {
78-
return Err("duplicate formats or chains specified");
79-
}
80-
if value.properties.is_empty() {
81-
return Err("no properties specified");
82-
}
83-
if !value.properties.iter().all_unique() {
84-
return Err("duplicate properties specified");
85-
}
52+
validate_price_feed_ids_or_symbols(&value.price_feed_ids, &value.symbols)?;
53+
validate_optional_nonempty_vec_has_unique_elements(
54+
&value.price_feed_ids,
55+
"no price feed ids specified",
56+
"duplicate price feed ids specified",
57+
)?;
58+
validate_optional_nonempty_vec_has_unique_elements(
59+
&value.symbols,
60+
"no symbols specified",
61+
"duplicate symbols specified",
62+
)?;
63+
validate_formats(&value.formats)?;
64+
validate_properties(&value.properties)?;
8665
Ok(Self(value))
8766
}
8867
}
@@ -134,40 +113,19 @@ impl<'de> Deserialize<'de> for PriceRequest {
134113

135114
impl PriceRequest {
136115
pub fn new(value: PriceRequestRepr) -> Result<Self, &'static str> {
137-
if value.price_feed_ids.is_none() && value.symbols.is_none() {
138-
return Err("either price feed ids or symbols must be specified");
139-
}
140-
if value.price_feed_ids.is_some() && value.symbols.is_some() {
141-
return Err("either price feed ids or symbols must be specified, not both");
142-
}
143-
144-
if let Some(ref ids) = value.price_feed_ids {
145-
if ids.is_empty() {
146-
return Err("no price feed ids specified");
147-
}
148-
if !ids.iter().all_unique() {
149-
return Err("duplicate price feed ids specified");
150-
}
151-
}
152-
153-
if let Some(ref symbols) = value.symbols {
154-
if symbols.is_empty() {
155-
return Err("no symbols specified");
156-
}
157-
if !symbols.iter().all_unique() {
158-
return Err("duplicate symbols specified");
159-
}
160-
}
161-
162-
if !value.formats.iter().all_unique() {
163-
return Err("duplicate formats or chains specified");
164-
}
165-
if value.properties.is_empty() {
166-
return Err("no properties specified");
167-
}
168-
if !value.properties.iter().all_unique() {
169-
return Err("duplicate properties specified");
170-
}
116+
validate_price_feed_ids_or_symbols(&value.price_feed_ids, &value.symbols)?;
117+
validate_optional_nonempty_vec_has_unique_elements(
118+
&value.price_feed_ids,
119+
"no price feed ids specified",
120+
"duplicate price feed ids specified",
121+
)?;
122+
validate_optional_nonempty_vec_has_unique_elements(
123+
&value.symbols,
124+
"no symbols specified",
125+
"duplicate symbols specified",
126+
)?;
127+
validate_formats(&value.formats)?;
128+
validate_properties(&value.properties)?;
171129
Ok(Self(value))
172130
}
173131
}
@@ -356,40 +314,19 @@ impl<'de> Deserialize<'de> for SubscriptionParams {
356314

357315
impl SubscriptionParams {
358316
pub fn new(value: SubscriptionParamsRepr) -> Result<Self, &'static str> {
359-
if value.price_feed_ids.is_none() && value.symbols.is_none() {
360-
return Err("either price feed ids or symbols must be specified");
361-
}
362-
if value.price_feed_ids.is_some() && value.symbols.is_some() {
363-
return Err("either price feed ids or symbols must be specified, not both");
364-
}
365-
366-
if let Some(ref ids) = value.price_feed_ids {
367-
if ids.is_empty() {
368-
return Err("no price feed ids specified");
369-
}
370-
if !ids.iter().all_unique() {
371-
return Err("duplicate price feed ids specified");
372-
}
373-
}
374-
375-
if let Some(ref symbols) = value.symbols {
376-
if symbols.is_empty() {
377-
return Err("no symbols specified");
378-
}
379-
if !symbols.iter().all_unique() {
380-
return Err("duplicate symbols specified");
381-
}
382-
}
383-
384-
if !value.formats.iter().all_unique() {
385-
return Err("duplicate formats or chains specified");
386-
}
387-
if value.properties.is_empty() {
388-
return Err("no properties specified");
389-
}
390-
if !value.properties.iter().all_unique() {
391-
return Err("duplicate properties specified");
392-
}
317+
validate_price_feed_ids_or_symbols(&value.price_feed_ids, &value.symbols)?;
318+
validate_optional_nonempty_vec_has_unique_elements(
319+
&value.price_feed_ids,
320+
"no price feed ids specified",
321+
"duplicate price feed ids specified",
322+
)?;
323+
validate_optional_nonempty_vec_has_unique_elements(
324+
&value.symbols,
325+
"no symbols specified",
326+
"duplicate symbols specified",
327+
)?;
328+
validate_formats(&value.formats)?;
329+
validate_properties(&value.properties)?;
393330
Ok(Self(value))
394331
}
395332
}
@@ -647,3 +584,53 @@ pub struct StreamUpdatedResponse {
647584
#[serde(flatten)]
648585
pub payload: JsonUpdate,
649586
}
587+
588+
// Common validation functions
589+
fn validate_price_feed_ids_or_symbols(
590+
price_feed_ids: &Option<Vec<PriceFeedId>>,
591+
symbols: &Option<Vec<String>>,
592+
) -> Result<(), &'static str> {
593+
if price_feed_ids.is_none() && symbols.is_none() {
594+
return Err("either price feed ids or symbols must be specified");
595+
}
596+
if price_feed_ids.is_some() && symbols.is_some() {
597+
return Err("either price feed ids or symbols must be specified, not both");
598+
}
599+
Ok(())
600+
}
601+
602+
fn validate_optional_nonempty_vec_has_unique_elements<T>(
603+
vec: &Option<Vec<T>>,
604+
empty_msg: &'static str,
605+
duplicate_msg: &'static str,
606+
) -> Result<(), &'static str>
607+
where
608+
T: Eq + std::hash::Hash,
609+
{
610+
if let Some(ref items) = vec {
611+
if items.is_empty() {
612+
return Err(empty_msg);
613+
}
614+
if !items.iter().all_unique() {
615+
return Err(duplicate_msg);
616+
}
617+
}
618+
Ok(())
619+
}
620+
621+
fn validate_properties(properties: &[PriceFeedProperty]) -> Result<(), &'static str> {
622+
if properties.is_empty() {
623+
return Err("no properties specified");
624+
}
625+
if !properties.iter().all_unique() {
626+
return Err("duplicate properties specified");
627+
}
628+
Ok(())
629+
}
630+
631+
fn validate_formats(formats: &[Format]) -> Result<(), &'static str> {
632+
if !formats.iter().all_unique() {
633+
return Err("duplicate formats or chains specified");
634+
}
635+
Ok(())
636+
}

0 commit comments

Comments
 (0)