Advertisement
Guest User

Untitled

a guest
May 19th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.27 KB | None | 0 0
  1. #[derive(Debug)]
  2. struct Error(String);
  3.  
  4. trait ValidateInput {
  5. fn validate_input(&self, field: &str) -> Result<(), Error>; //New 'field'
  6. }
  7.  
  8. // Method for ion validation
  9. fn validate_input_string(input: impl AsRef<str>, field: &str) -> Result<(), Error> {
  10. let input = input.as_ref();
  11. if input == "foo" {
  12. Err(Error(format!("Invalid string in field: '{}'", field)))
  13. }
  14. else {
  15. Ok(())
  16. }
  17. }
  18.  
  19. macro_rules! stringify_replace_self {
  20. ($e: expr, $replacement: expr) => {{
  21. let s = stringify!($e);
  22. if !$replacement.is_empty() {
  23. s.replace("&self", $replacement)
  24. }
  25. else {
  26. s.replace("&self.", $replacement)
  27. }
  28. }}
  29. }
  30.  
  31. macro_rules! fn_field {
  32. ($self_name: expr, $field: expr, $func: expr) => {
  33. $func($field, &stringify_replace_self!($field, $self_name))
  34. }
  35. }
  36.  
  37. macro_rules! fn_index {
  38. ($self_name: expr, $field: expr, $index: expr, $func: expr) => {
  39. $func($field, &format!("{}[{}]", $self_name, $index))
  40. }
  41. }
  42.  
  43. struct Input {
  44. foo: Bar
  45. }
  46.  
  47. struct Bar {
  48. bar: Vec<String>
  49. }
  50.  
  51. impl ValidateInput for String {
  52. fn validate_input(&self, field: &str) -> Result<(), Error> {
  53. validate_input_string(self, field)
  54. }
  55. }
  56.  
  57. impl<S: ValidateInput> ValidateInput for Vec<S> {
  58. fn validate_input(&self, field: &str) -> Result<(), Error> {
  59. self.iter()
  60. .enumerate()
  61. .map(|(index, i)| fn_index!(field, i, index, ValidateInput::validate_input))
  62. .collect::<Result<Vec<_>, Error>>()?;
  63. Ok(())
  64. }
  65. }
  66.  
  67. // Derived from proc macro:
  68. impl ValidateInput for Input {
  69. fn validate_input(&self, field: &str) -> Result<(), Error> {
  70. // Add validation with: fn_field!(field, &self.foo, validate_input_string)?;
  71. fn_field!(field, &self.foo, ValidateInput::validate_input)?;
  72. Ok(())
  73. }
  74. }
  75.  
  76. // Derived from proc macro:
  77. impl ValidateInput for Bar {
  78. fn validate_input(&self, field: &str) -> Result<(), Error> {
  79. fn_field!(field, &self.bar, ValidateInput::validate_input)?;
  80. Ok(())
  81. }
  82. }
  83.  
  84.  
  85. fn main() -> Result<(), Error> {
  86. let input = Input {
  87. foo: Bar{
  88. bar: vec![
  89. "bar".to_string(),
  90. "foo".to_string()
  91. ]
  92. }
  93. };
  94.  
  95. input.validate_input("")
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement