rust/hg-core/src/config/layer.rs
changeset 46447 0cb1b02228a6
parent 46435 2e2033081274
child 46481 0d734c0ae1cf
equal deleted inserted replaced
46446:1dcd9c9975ed 46447:0cb1b02228a6
     5 //      Raphaël Gomès <rgomes@octobus.net>
     5 //      Raphaël Gomès <rgomes@octobus.net>
     6 //
     6 //
     7 // This software may be used and distributed according to the terms of the
     7 // This software may be used and distributed according to the terms of the
     8 // GNU General Public License version 2 or any later version.
     8 // GNU General Public License version 2 or any later version.
     9 
     9 
       
    10 use crate::errors::{HgError, IoResultExt};
    10 use crate::utils::files::{
    11 use crate::utils::files::{
    11     get_bytes_from_path, get_path_from_bytes, read_whole_file,
    12     get_bytes_from_path, get_path_from_bytes, read_whole_file,
    12 };
    13 };
    13 use format_bytes::format_bytes;
    14 use format_bytes::format_bytes;
    14 use lazy_static::lazy_static;
    15 use lazy_static::lazy_static;
    97 
    98 
    98         while let Some((index, bytes)) = lines_iter.next() {
    99         while let Some((index, bytes)) = lines_iter.next() {
    99             if let Some(m) = INCLUDE_RE.captures(&bytes) {
   100             if let Some(m) = INCLUDE_RE.captures(&bytes) {
   100                 let filename_bytes = &m[1];
   101                 let filename_bytes = &m[1];
   101                 let filename_to_include = get_path_from_bytes(&filename_bytes);
   102                 let filename_to_include = get_path_from_bytes(&filename_bytes);
   102                 match read_include(&src, &filename_to_include) {
   103                 let (include_src, result) =
   103                     (include_src, Ok(data)) => {
   104                     read_include(&src, &filename_to_include);
   104                         layers.push(current_layer);
   105                 let data = result.for_file(filename_to_include)?;
   105                         layers.extend(Self::parse(&include_src, &data)?);
   106                 layers.push(current_layer);
   106                         current_layer =
   107                 layers.extend(Self::parse(&include_src, &data)?);
   107                             Self::new(ConfigOrigin::File(src.to_owned()));
   108                 current_layer = Self::new(ConfigOrigin::File(src.to_owned()));
   108                     }
       
   109                     (_, Err(e)) => {
       
   110                         return Err(ConfigError::IncludeError {
       
   111                             path: filename_to_include.to_owned(),
       
   112                             io_error: e,
       
   113                         })
       
   114                     }
       
   115                 }
       
   116             } else if let Some(_) = EMPTY_RE.captures(&bytes) {
   109             } else if let Some(_) = EMPTY_RE.captures(&bytes) {
   117             } else if let Some(m) = SECTION_RE.captures(&bytes) {
   110             } else if let Some(m) = SECTION_RE.captures(&bytes) {
   118                 section = m[1].to_vec();
   111                 section = m[1].to_vec();
   119             } else if let Some(m) = ITEM_RE.captures(&bytes) {
   112             } else if let Some(m) = ITEM_RE.captures(&bytes) {
   120                 let item = m[1].to_vec();
   113                 let item = m[1].to_vec();
   143             } else if let Some(m) = UNSET_RE.captures(&bytes) {
   136             } else if let Some(m) = UNSET_RE.captures(&bytes) {
   144                 if let Some(map) = current_layer.sections.get_mut(&section) {
   137                 if let Some(map) = current_layer.sections.get_mut(&section) {
   145                     map.remove(&m[1]);
   138                     map.remove(&m[1]);
   146                 }
   139                 }
   147             } else {
   140             } else {
   148                 return Err(ConfigError::Parse {
   141                 return Err(ConfigParseError {
   149                     origin: ConfigOrigin::File(src.to_owned()),
   142                     origin: ConfigOrigin::File(src.to_owned()),
   150                     line: Some(index + 1),
   143                     line: Some(index + 1),
   151                     bytes: bytes.to_owned(),
   144                     bytes: bytes.to_owned(),
   152                 });
   145                 }
       
   146                 .into());
   153             }
   147             }
   154         }
   148         }
   155         if !current_layer.is_empty() {
   149         if !current_layer.is_empty() {
   156             layers.push(current_layer);
   150             layers.push(current_layer);
   157         }
   151         }
   224             ConfigOrigin::Environment(e) => e.to_owned(),
   218             ConfigOrigin::Environment(e) => e.to_owned(),
   225         }
   219         }
   226     }
   220     }
   227 }
   221 }
   228 
   222 
       
   223 #[derive(Debug)]
       
   224 pub struct ConfigParseError {
       
   225     pub origin: ConfigOrigin,
       
   226     pub line: Option<usize>,
       
   227     pub bytes: Vec<u8>,
       
   228 }
       
   229 
   229 #[derive(Debug, derive_more::From)]
   230 #[derive(Debug, derive_more::From)]
   230 pub enum ConfigError {
   231 pub enum ConfigError {
   231     Parse {
   232     Parse(ConfigParseError),
   232         origin: ConfigOrigin,
   233     Other(HgError),
   233         line: Option<usize>,
       
   234         bytes: Vec<u8>,
       
   235     },
       
   236     /// Failed to include a sub config file
       
   237     IncludeError {
       
   238         path: PathBuf,
       
   239         io_error: std::io::Error,
       
   240     },
       
   241     /// Any IO error that isn't expected
       
   242     #[from]
       
   243     IO(std::io::Error),
       
   244 }
   234 }
   245 
   235 
   246 fn make_regex(pattern: &'static str) -> Regex {
   236 fn make_regex(pattern: &'static str) -> Regex {
   247     Regex::new(pattern).expect("expected a valid regex")
   237     Regex::new(pattern).expect("expected a valid regex")
   248 }
   238 }