| 830 | } |
| 831 | |
| 832 | pub fn parse_csv<T>(value: Option<&String>, field: &str) -> ApiResult<Vec<T>> |
| 833 | where |
| 834 | T: FromStr, |
| 835 | <T as FromStr>::Err: std::fmt::Display, |
| 836 | { |
| 837 | let Some(value) = value else { |
| 838 | return Ok(Vec::new()); |
| 839 | }; |
| 840 | value |
| 841 | .split(',') |
| 842 | .filter(|item| !item.trim().is_empty()) |
| 843 | .map(|item| { |
| 844 | item.trim() |
| 845 | .parse() |
| 846 | .map_err(|_| ApiError::bad_request(format!("invalid {field}: {item}"))) |
| 847 | }) |
| 848 | .collect() |
| 849 | } |
| 850 | |
| 851 | pub fn parse_optional<T>(value: Option<&String>, field: &str) -> ApiResult<Option<T>> |
| 852 | where |