directories-rs icon indicating copy to clipboard operation
directories-rs copied to clipboard

$XDG_DATA_DIRS

Open sanpii opened this issue 7 years ago • 3 comments

Hello,

I don’t find a way to retreive $XDG_DATA_DIRS. Is it a missing feature?

From XDG specifications:

$XDG_DATA_DIRS defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS should be seperated with a colon ':'.

If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used.

After reading the source code, I think I need a SystemDirs likes ProjectDir.

sanpii avatar Jun 30 '18 08:06 sanpii

Hi @sanpii,

thanks for reporting this issue! It's not implemented, but I thought about what would be necessary a while ago. In fact, we even came up with the same struct name. :-)

One of the problems is /etc/xdg as the default for $XDG_CONFIG_DIRS, which I just don't want to support. I think it's a spec oversight/misinterpretation of the spec from the time the spec was solely focused on applications developed internally by the XDG project.

That's why I avoided this topic until now. From my point of view, the spec needs to be fixed first.

soc avatar Jun 30 '18 12:06 soc

I would like to see this feature supported as well, but with a different interface.

From my interpretation of the specification, the main point is a preference order for finding files and directories. It is very explicit about the fact that files in these paths are not expected to be writable. Additionally, I would like to point out the following paragraph in the specification:

The base directory defined by $XDG_DATA_HOME is considered more important than any of the base directories defined by $XDG_DATA_DIRS. The base directory defined by $XDG_CONFIG_HOME is considered more important than any of the base directories defined by $XDG_CONFIG_DIRS.

In particular, the path given by $HOME/.local/config would be searched before /etc/xdg in case no environment variables are set. It might therefore be included for backwards compatibility reasons.

I would have thought of an interface (and implementation proposition) like this:

impl BaseDirs {
  // Returns an iterable set of directories for finding data files.
  //
  // Iterates just over `data_dir` on most platforms but respects `XDG_DATA_DIRS` on Linux.
  fn data_dirs(&self) -> DataDirs { … }

  // Returns an iterable set of directories for finding config files.
  //
  // Iterates just over `config_dir` on most platforms but respects `XDG_CONFIG_DIRS` on Linux.
  fn config_dirs(&self) -> ConfigDirs { … }
}

struct DataDirs<'a> {
  base: &'a BaseDirs,
  …  // We probably need to keep track of an index
}

impl<'a> Iterator for DataDirs<'a> {
  type Item = &'a Path;
  … 
}

Small modifications of BaseDir are of course be necessary, for example an additional member:

struct BaseDirs {
  …,
  data_dirs: Vec<PathBuf>,
  config_dirs: Vec<PathBuf>,
}

This would make it possible to add the necessary find_data_file interfaces by the library user while providing enough semantics to make it easier to follow the specification.

Prior Art: the Qt libraries for C++ although the missing Iterator interface makes the implementation of find by users harder than it needs to be in Rust.

197g avatar Aug 14 '18 18:08 197g

Something like the above proposal, extended to ProjectDirs, would be very useful.

Ralith avatar Oct 27 '19 20:10 Ralith