Skip to content
This repository was archived by the owner on Oct 19, 2024. It is now read-only.

Commit c6dbf00

Browse files
authored
feat: add from_str for Remapping (#583)
1 parent d53ca0e commit c6dbf00

File tree

1 file changed

+41
-11
lines changed

1 file changed

+41
-11
lines changed

Diff for: ethers-solc/src/remappings.rs

+41-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{error::SolcError, Result};
22
use serde::{Deserialize, Serialize};
3-
use std::fmt;
3+
use std::{fmt, str::FromStr};
44

55
const DAPPTOOLS_CONTRACTS_DIR: &str = "src";
66
const JS_CONTRACTS_DIR: &str = "contracts";
@@ -42,6 +42,31 @@ pub struct Remapping {
4242
pub path: String,
4343
}
4444

45+
#[derive(thiserror::Error, Debug, PartialEq, PartialOrd)]
46+
pub enum RemappingError {
47+
#[error("no prefix found")]
48+
NoPrefix,
49+
#[error("no target found")]
50+
NoTarget,
51+
}
52+
53+
impl FromStr for Remapping {
54+
type Err = RemappingError;
55+
56+
fn from_str(remapping: &str) -> std::result::Result<Self, Self::Err> {
57+
let mut split = remapping.split('=');
58+
let name = split.next().ok_or_else(|| RemappingError::NoPrefix)?.to_string();
59+
if name.is_empty() {
60+
return Err(RemappingError::NoPrefix)
61+
}
62+
let path = split.next().ok_or_else(|| RemappingError::NoTarget)?.to_string();
63+
if path.is_empty() {
64+
return Err(RemappingError::NoTarget)
65+
}
66+
Ok(Remapping { name, path })
67+
}
68+
}
69+
4570
impl Serialize for Remapping {
4671
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
4772
where
@@ -57,16 +82,7 @@ impl<'de> Deserialize<'de> for Remapping {
5782
D: serde::de::Deserializer<'de>,
5883
{
5984
let remapping = String::deserialize(deserializer)?;
60-
let mut split = remapping.split('=');
61-
let name = split
62-
.next()
63-
.ok_or_else(|| serde::de::Error::custom("no remapping prefix found"))?
64-
.to_string();
65-
let path = split
66-
.next()
67-
.ok_or_else(|| serde::de::Error::custom("no remapping path found"))?
68-
.to_string();
69-
Ok(Remapping { name, path })
85+
Remapping::from_str(&remapping).map_err(|e| serde::de::Error::custom(e))
7086
}
7187
}
7288

@@ -163,6 +179,20 @@ impl Remapping {
163179
mod tests {
164180
use super::*;
165181

182+
#[test]
183+
fn serde() {
184+
let remapping = "oz=../b/c/d";
185+
let remapping = Remapping::from_str(&remapping).unwrap();
186+
assert_eq!(remapping.name, "oz".to_string());
187+
assert_eq!(remapping.path, "../b/c/d".to_string());
188+
189+
let err = Remapping::from_str("").unwrap_err();
190+
assert_eq!(err, RemappingError::NoPrefix);
191+
192+
let err = Remapping::from_str("oz=").unwrap_err();
193+
assert_eq!(err, RemappingError::NoTarget);
194+
}
195+
166196
// https://doc.rust-lang.org/rust-by-example/std_misc/fs.html
167197
fn touch(path: &std::path::Path) -> std::io::Result<()> {
168198
match std::fs::OpenOptions::new().create(true).write(true).open(path) {

0 commit comments

Comments
 (0)