1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/// Internal namespace.
pub( crate ) mod private
{

  /// Adds indentation and optional prefix/postfix to each line of the given string.
  ///
  /// This function iterates over each line in the input string and applies the specified
  /// prefix and postfix to it, effectively indenting the string and optionally wrapping
  /// each line with additional content.
  ///
  /// # Parameters
  /// - `prefix` : The string to prepend to each line, typically used for indentation.
  /// - `src` : The source string to be indented and modified.
  /// - `postfix` : The string to append to each line, can be used for line terminators or other suffixes.
  ///
  /// # Type Parameters
  /// - `Prefix` : A type that can be referenced as a string slice, for the prefix.
  /// - `Src` : A type that can be referenced as a string slice, for the source string.
  /// - `Postfix` : A type that can be referenced as a string slice, for the postfix.
  ///
  /// # Returns
  /// A `String` that represents the original `src` string with `prefix` and `postfix` applied to each line.
  ///
  /// # Example
  /// ```
  /// use strs_tools::exposed::*;
  ///
  /// let input = "Line 1\nLine 2\nLine 3";
  /// let indented = indentation( "  ", input, ";" );
  /// assert_eq!( indented, "  Line 1;\n  Line 2;\n  Line 3;" );
  ///
  /// // Demonstrating the function's handling of trailing newlines
  /// let input_with_newline = "Line 1\nLine 2\nLine 3\n";
  /// let indented_with_newline = indentation( "  ", input_with_newline, ";" );
  /// assert_eq!( indented_with_newline, "  Line 1;\n  Line 2;\n  Line 3;\n  ;" );
  /// ```
  ///
  /// In the example above, `indentation` is used to add two spaces before each line
  /// and a semicolon at the end of each line. The function also demonstrates handling
  /// of input strings that end with a newline character by appending an additional line
  /// consisting only of the prefix and postfix.

  pub fn indentation< Prefix, Src, Postfix >( prefix : Prefix, src : Src, postfix : Postfix ) -> String
  where
    Prefix : AsRef< str >,
    Src : AsRef< str >,
    Postfix : AsRef< str >,
  {
    let prefix = prefix.as_ref();
    let postfix = postfix.as_ref();
    let src = src.as_ref();

    let mut result = src
    .lines()
    .enumerate()
    .fold( String::new(), | mut a, b |
    {
      if b.0 > 0
      {
        a.push_str( "\n" );
      }
      a.push_str( prefix );
      a.push_str( &b.1 );
      a.push_str( postfix );
      a
    });

    if src.ends_with( "\n" ) || src.ends_with( "\n\r" ) || src.ends_with( "\r\n" )
    {
      result.push_str( "\n" );
      result.push_str( prefix );
      result.push_str( postfix );
    }

    result
  }

}

#[ doc( inline ) ]
#[ allow( unused_imports ) ]
pub use protected::*;

/// Protected namespace of the module.
pub mod protected
{
  pub use super::orphan::*;
  #[ allow( unused_imports ) ]
  pub use super::private::
  {
  };
}

/// Parented namespace of the module.
pub mod orphan
{
  #[ allow( unused_imports ) ]
  pub use super::exposed::*;
  #[ allow( unused_imports ) ]
  pub use super::private::
  {
  };
}

/// Exposed namespace of the module.
pub mod exposed
{
  pub use super::protected as indentation;

  #[ allow( unused_imports ) ]
  pub use super::private::
  {
    indentation,
  };
}

/// Namespace of the module to include with `use module::*`.
pub mod prelude
{
}