infer-0.19.0/.cargo_vcs_info.json 0000644 00000000136 00000000001 0012226 0 ustar {
"git": {
"sha1": "4256ea07165a9393186b6c190541fac4b5e6f9f5"
},
"path_in_vcs": ""
} infer-0.19.0/.chglog/CHANGELOG.tpl.md 0000644 0000000 0000000 00000001337 10461020230 0014752 0 ustar 0000000 0000000 ## Changelog
{{ range .Versions }}
## {{ if .Tag.Previous }}{{ .Tag.Name }}{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
{{ if .CommitGroups -}}
{{ range .CommitGroups -}}
### {{ .Title }}
{{ range .Commits -}}
- {{.Hash.Short}} {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ if .Subject }}{{ .Subject }}{{ else }}{{ .Header }}{{ end }}
{{ end }}
{{ end -}}
### Commits
{{ range .Commits -}}
- {{.Hash.Short}} {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ if .Subject }}{{ .Subject }}{{ else }}{{ .Header }}{{ end }}
{{ end }}
{{ end -}}
{{- if .NoteGroups -}}
{{ range .NoteGroups -}}
### {{ .Title }}
{{ range .Notes }}
{{ .Body }}
{{ end }}
{{ end -}}
{{ end -}}
{{ end -}} infer-0.19.0/.chglog/config.yml 0000644 0000000 0000000 00000001015 10461020230 0014324 0 ustar 0000000 0000000 style: github
template: CHANGELOG.tpl.md
info:
title: CHANGELOG
repository_url: https://github.com/bojand/infer
options:
commits:
filters:
Type:
- docs
- enhance
- feat
- fix
- build
commit_groups:
title_maps:
docs: Documentation
enhance: Enhancements
feat: Features
fix: Bug Fixes
build: Build
header:
pattern: "^(\\w*)?\\:\\s(.*)$"
pattern_maps:
- Type
- Subject
notes:
keywords:
- BREAKING CHANGE infer-0.19.0/.github/workflows/build.yml 0000644 0000000 0000000 00000002131 10461020230 0016232 0 ustar 0000000 0000000 name: build
on:
push:
branches:
- master
paths:
- 'Cargo*'
- 'src/**'
- 'tests/**'
- 'testdata/**'
pull_request:
branches:
- master
paths:
- 'Cargo*'
- 'src/**'
- 'tests/**'
- 'testdata/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Install rustfmt
run: rustup component add rustfmt
- name: Install clippy
run: rustup component add clippy
- name: Check format
run: cargo fmt --all -- --check
- name: Lint (all features)
run: cargo clippy --all-targets --all-features --examples -- -D clippy::all
- name: Lint (no_std)
run: cargo clippy --all-targets --no-default-features --features alloc -- -D clippy::all
- name: Lint (no_alloc)
run: cargo clippy --all-targets --no-default-features -- -D clippy::all
- name: Test (default)
run: cargo test --verbose
- name: Test (no_std)
run: cargo test --no-default-features --features alloc --verbose
- name: Test (no_alloc)
run: cargo test --no-default-features --verbose
infer-0.19.0/.github/workflows/release.yml 0000644 0000000 0000000 00000004122 10461020230 0016555 0 ustar 0000000 0000000 name: release
on:
push:
tags:
- v*
jobs:
github_build:
name: GitHub Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Install rustfmt
run: rustup component add rustfmt
- name: Install clippy
run: rustup component add clippy
- name: Check format
run: cargo fmt --all -- --check
- name: Lint (all features)
run: cargo clippy --all-targets --all-features -- -D clippy::all
- name: Lint (no_std)
run: cargo clippy --all-targets --no-default-features --features alloc -- -D clippy::all
- name: Lint (no_alloc)
run: cargo clippy --all-targets --no-default-features -- -D clippy::all
- name: Test (default)
run: cargo test --verbose
- name: Test (no_std)
run: cargo test --no-default-features --features alloc --verbose
- name: Test (no_alloc)
run: cargo test --no-default-features --verbose
github_release:
name: Create GitHub Release
needs: github_build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Generate release notes
run: |
export PATH=$PATH:$(go env GOPATH)/bin
go install github.com/git-chglog/git-chglog/cmd/git-chglog@latest
git-chglog -c .chglog/config.yml $(git describe --tags) > RELEASE.md
- name: Create GitHub release ${{ matrix.target }}
uses: softprops/action-gh-release@v1
with:
body_path: RELEASE.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Publish to Crates.io
cargo_publish:
name: Publish Cargo Package
needs: github_build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- run: cargo login $CRATES_IO_TOKEN
- run: cargo publish
env:
CRATES_IO_TOKEN: ${{ secrets.CRATES_IO_TOKEN }} infer-0.19.0/.gitignore 0000644 0000000 0000000 00000000500 10461020230 0013001 0 ustar 0000000 0000000 # Generated by Cargo
# will have compiled files and executables
/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
infer-0.19.0/Cargo.lock 0000644 00000001727 00000000001 0010210 0 ustar # This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cfb"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f"
dependencies = [
"byteorder",
"fnv",
"uuid",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "infer"
version = "0.19.0"
dependencies = [
"cfb",
]
[[package]]
name = "uuid"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
infer-0.19.0/Cargo.toml 0000644 00000002442 00000000001 0010226 0 ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
name = "infer"
version = "0.19.0"
authors = ["Bojan "]
build = false
exclude = [
"/testdata",
"/tests",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Small crate to infer file type based on magic number signatures"
homepage = "https://github.com/bojand/infer"
documentation = "https://docs.rs/infer"
readme = "README.md"
keywords = [
"magic-number",
"filetype",
"mime",
"mime-types",
"no_std",
]
license = "MIT"
repository = "https://github.com/bojand/infer"
[lib]
name = "infer"
path = "src/lib.rs"
[[example]]
name = "file"
path = "examples/file.rs"
required-features = ["std"]
[dependencies.cfb]
version = "0.7.0"
optional = true
[features]
alloc = []
default = ["std"]
std = [
"alloc",
"cfb",
]
infer-0.19.0/Cargo.toml.orig 0000644 0000000 0000000 00000001225 10461020230 0013705 0 ustar 0000000 0000000 [package]
name = "infer"
version = "0.19.0"
authors = ["Bojan "]
edition = "2018"
description = "Small crate to infer file type based on magic number signatures"
license = "MIT"
keywords = ["magic-number", "filetype", "mime", "mime-types", "no_std"]
readme = "README.md"
homepage = "https://github.com/bojand/infer"
repository = "https://github.com/bojand/infer"
documentation = "https://docs.rs/infer"
exclude = ["/testdata", "/tests"]
[features]
default = ["std"]
std = ["alloc", "cfb"]
alloc = []
[[example]]
name = "file"
path = "examples/file.rs"
required-features = ["std"]
[dependencies]
cfb = { version = "0.7.0", optional = true }
infer-0.19.0/LICENSE 0000644 0000000 0000000 00000002046 10461020230 0012025 0 ustar 0000000 0000000 MIT License
Copyright (c) 2019 Bojan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
infer-0.19.0/README.md 0000644 0000000 0000000 00000014525 10461020230 0012304 0 ustar 0000000 0000000 # infer

[](https://crates.io/crates/infer)
[](https://docs.rs/infer)
Small crate to infer file and MIME type by checking the
[magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)) signature.
Adaptation of [filetype](https://github.com/h2non/filetype) Go package ported to Rust.
Does not require magic file database (i.e. `/etc/magic`).
## Features
- Supports a [wide range](#supported-types) of file types
- Provides file extension and MIME type
- File discovery by extension or MIME type
- File discovery by class (image, video, audio...)
- Supports custom new types and matchers
## Installation
This crate works with Cargo and is on [crates.io](https://crates.io/crates/infer).
Add it to your `Cargo.toml` like so:
```toml
[dependencies]
infer = "0.3"
```
If you are not using the custom matcher or the file type from file path functionality you
can make this crate even lighter by importing it with no default features, like so:
```toml
[dependencies]
infer = { version = "0.3", default-features = false }
```
## no_std and no_alloc support
This crate supports `no_std` and `no_alloc` environments. `std` support is enabled by default,
but you can disable it by importing the crate with no default features, making it depend
only on the Rust `core` Library.
`alloc` has to be enabled to be able to use custom file matchers.
`std` has to be enabled to be able to get the file type from a file given the file path.
## Examples
Most operations can be done via _top level functions_, but they are also available through the `Infer`
struct, which must be used when dealing custom matchers.
### Get the type of a buffer
```rust
let buf = [0xFF, 0xD8, 0xFF, 0xAA];
let kind = infer::get(&buf).expect("file type is known");
assert_eq!(kind.mime_type(), "image/jpeg");
assert_eq!(kind.extension(), "jpg");
```
### Check file type by path
```rust
let kind = infer::get_from_path("testdata/sample.jpg")
.expect("file read successfully")
.expect("file type is known");
assert_eq!(kind.mime_type(), "image/jpeg");
assert_eq!(kind.extension(), "jpg");
```
### Check for specific type
```rust
let buf = [0xFF, 0xD8, 0xFF, 0xAA];
assert!(infer::image::is_jpeg(&buf));
```
### Check for specific type class
```rust
let buf = [0xFF, 0xD8, 0xFF, 0xAA];
assert!(infer::is_image(&buf));
```
### Adds a custom file type matcher
```rust
fn custom_matcher(buf: &[u8]) -> bool {
return buf.len() >= 3 && buf[0] == 0x10 && buf[1] == 0x11 && buf[2] == 0x12;
}
let mut info = infer::Infer::new();
info.add("custom/foo", "foo", custom_matcher);
let buf = [0x10, 0x11, 0x12, 0x13];
let kind = info.get(&buf).expect("file type is known");
assert_eq!(kind.mime_type(), "custom/foo");
assert_eq!(kind.extension(), "foo");
```
## Supported types
#### Image
- **jpg** - `image/jpeg`
- **png** - `image/png`
- **gif** - `image/gif`
- **webp** - `image/webp`
- **cr2** - `image/x-canon-cr2`
- **tif** - `image/tiff`
- **bmp** - `image/bmp`
- **heif** - `image/heif`
- **avif** - `image/avif`
- **jxr** - `image/vnd.ms-photo`
- **psd** - `image/vnd.adobe.photoshop`
- **ico** - `image/vnd.microsoft.icon`
- **ora** - `image/openraster`
- **djvu** - `image/vnd.djvu`
#### Video
- **mp4** - `video/mp4`
- **m4v** - `video/x-m4v`
- **mkv** - `video/x-matroska`
- **webm** - `video/webm`
- **mov** - `video/quicktime`
- **avi** - `video/x-msvideo`
- **wmv** - `video/x-ms-wmv`
- **mpg** - `video/mpeg`
- **flv** - `video/x-flv`
#### Audio
- **mid** - `audio/midi`
- **mp3** - `audio/mpeg`
- **m4a** - `audio/m4a`
- **ogg** - `audio/ogg`
- **flac** - `audio/x-flac`
- **wav** - `audio/x-wav`
- **amr** - `audio/amr`
- **aac** - `audio/aac`
- **aiff** - `audio/x-aiff`
- **dsf** - `audio/x-dsf`
- **ape** - `audio/x-ape`
#### Archive
- **epub** - `application/epub+zip`
- **zip** - `application/zip`
- **tar** - `application/x-tar`
- **rar** - `application/vnd.rar`
- **gz** - `application/gzip`
- **bz2** - `application/x-bzip2`
- **bz3** - `application/vnd.bzip3`
- **7z** - `application/x-7z-compressed`
- **xz** - `application/x-xz`
- **pdf** - `application/pdf`
- **swf** - `application/x-shockwave-flash`
- **rtf** - `application/rtf`
- **eot** - `application/octet-stream`
- **ps** - `application/postscript`
- **sqlite** - `application/vnd.sqlite3`
- **nes** - `application/x-nintendo-nes-rom`
- **crx** - `application/x-google-chrome-extension`
- **cab** - `application/vnd.ms-cab-compressed`
- **deb** - `application/vnd.debian.binary-package`
- **ar** - `application/x-unix-archive`
- **Z** - `application/x-compress`
- **lz** - `application/x-lzip`
- **rpm** - `application/x-rpm`
- **dcm** - `application/dicom`
- **zst** - `application/zstd`
- **lz4** - `application/x-lz4`
- **msi** - `application/x-ole-storage`
- **cpio** - `application/x-cpio`
- **par2** - `application/x-par2`
#### Book
- **epub** - `application/epub+zip`
- **mobi** - `application/x-mobipocket-ebook`
#### Documents
- **doc** - `application/msword`
- **docx** - `application/vnd.openxmlformats-officedocument.wordprocessingml.document`
- **xls** - `application/vnd.ms-excel`
- **xlsx** - `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`
- **ppt** - `application/vnd.ms-powerpoint`
- **pptx** - `application/vnd.openxmlformats-officedocument.presentationml.presentation`
- **odt** - `application/vnd.oasis.opendocument.text`
- **ods** - `application/vnd.oasis.opendocument.spreadsheet`
- **odp** - `application/vnd.oasis.opendocument.presentation`
#### Font
- **woff** - `application/font-woff`
- **woff2** - `application/font-woff`
- **ttf** - `application/font-sfnt`
- **otf** - `application/font-sfnt`
#### Application
- **wasm** - `application/wasm`
- **exe** - `application/vnd.microsoft.portable-executable`
- **dll** - `application/vnd.microsoft.portable-executable`
- **elf** - `application/x-executable`
- **bc** - `application/llvm`
- **mach** - `application/x-mach-binary`
- **class** - `application/java`
- **dex** - `application/vnd.android.dex`
- **dey** - `application/vnd.android.dey`
- **der** - `application/x-x509-ca-cert`
- **obj** - `application/x-executable`
## Known Issues
- `exe` and `dll` have the same magic number so it's not possible to tell which one just based on the binary data. `exe` is returned for all.
## License
MIT
infer-0.19.0/examples/file.rs 0000644 0000000 0000000 00000001625 10461020230 0014125 0 ustar 0000000 0000000 use std::env::args;
use std::process::exit;
fn main() {
let mut args = args();
let path = match args.nth(1) {
Some(path) => path,
None => {
eprintln!("Please specify the file path");
exit(1);
}
};
match infer::get_from_path(path) {
Ok(Some(info)) => {
println!("Through the arcane magic of this crate we determined the file type to be");
println!("mime type: {}", info.mime_type());
println!("extension: {}", info.extension());
}
Ok(None) => {
eprintln!("Unknown file type 😞");
eprintln!("If you think infer should be able to recognize this file type open an issue on GitHub!");
exit(1);
}
Err(e) => {
eprintln!("Looks like something went wrong 😔");
eprintln!("{}", e);
exit(1);
}
}
}
infer-0.19.0/src/lib.rs 0000644 0000000 0000000 00000040755 10461020230 0012734 0 ustar 0000000 0000000 /*!
Small crate to infer file and MIME type by checking the
[magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)) signature.
# Examples
### Get the type of a buffer
```rust
let buf = [0xFF, 0xD8, 0xFF, 0xAA];
let kind = infer::get(&buf).expect("file type is known");
assert_eq!(kind.mime_type(), "image/jpeg");
assert_eq!(kind.extension(), "jpg");
assert_eq!(kind.matcher_type(), infer::MatcherType::Image);
```
### Check file type by path
```rust
# #[cfg(feature = "std")]
# fn run() {
let kind = infer::get_from_path("testdata/sample.jpg")
.expect("file read successfully")
.expect("file type is known");
assert_eq!(kind.mime_type(), "image/jpeg");
assert_eq!(kind.extension(), "jpg");
# }
```
### Check for specific type
```rust
let buf = [0xFF, 0xD8, 0xFF, 0xAA];
assert!(infer::image::is_jpeg(&buf));
```
### Check for specific type class
```rust
let buf = [0xFF, 0xD8, 0xFF, 0xAA];
assert!(infer::is_image(&buf));
```
### Adds a custom file type matcher
Here we actually need to use the `Infer` struct to be able to declare custom matchers.
```rust
# #[cfg(feature = "alloc")]
# fn run() {
fn custom_matcher(buf: &[u8]) -> bool {
return buf.len() >= 3 && buf[0] == 0x10 && buf[1] == 0x11 && buf[2] == 0x12;
}
let mut info = infer::Infer::new();
info.add("custom/foo", "foo", custom_matcher);
let buf = [0x10, 0x11, 0x12, 0x13];
let kind = info.get(&buf).unwrap();
assert_eq!(kind.mime_type(), "custom/foo");
assert_eq!(kind.extension(), "foo");
# }
```
*/
#![crate_name = "infer"]
#![doc(html_root_url = "https://docs.rs/infer/latest")]
#![forbid(unsafe_code)]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "alloc")]
extern crate alloc;
mod map;
mod matchers;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::fmt;
#[cfg(feature = "std")]
use std::fs::File;
#[cfg(feature = "std")]
use std::io::{self, Read};
#[cfg(feature = "std")]
use std::path::Path;
pub use map::MatcherType;
use map::{WrapMatcher, MATCHER_MAP};
/// All the supported matchers categorized and exposed as functions
pub use matchers::*;
/// Matcher function
pub type Matcher = fn(buf: &[u8]) -> bool;
/// Generic information for a type
#[derive(Copy, Clone)]
pub struct Type {
matcher_type: MatcherType,
mime_type: &'static str,
extension: &'static str,
matcher: WrapMatcher,
}
impl Type {
pub(crate) const fn new_static(
matcher_type: MatcherType,
mime_type: &'static str,
extension: &'static str,
matcher: WrapMatcher,
) -> Self {
Self {
matcher_type,
mime_type,
extension,
matcher,
}
}
/// Returns a new `Type` with matcher and extension.
pub fn new(
matcher_type: MatcherType,
mime_type: &'static str,
extension: &'static str,
matcher: Matcher,
) -> Self {
Self::new_static(matcher_type, mime_type, extension, WrapMatcher(matcher))
}
/// Returns the type of matcher
///
/// # Examples
///
/// ```rust
/// let info = infer::Infer::new();
/// let buf = [0xFF, 0xD8, 0xFF, 0xAA];
/// let kind = info.get(&buf).expect("file type is known");
///
/// assert_eq!(kind.matcher_type(), infer::MatcherType::Image);
/// ```
pub const fn matcher_type(&self) -> MatcherType {
self.matcher_type
}
/// Returns the mime type
pub const fn mime_type(&self) -> &'static str {
self.mime_type
}
/// Returns the file extension
pub const fn extension(&self) -> &'static str {
self.extension
}
/// Checks if buf matches this Type
fn matches(&self, buf: &[u8]) -> bool {
(self.matcher.0)(buf)
}
}
impl fmt::Debug for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Type")
.field("matcher_type", &self.matcher_type)
.field("mime_type", &self.mime_type)
.field("extension", &self.extension)
.finish()
}
}
impl fmt::Display for Type {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(self.mime_type, f)
}
}
impl PartialEq for Type {
fn eq(&self, other: &Self) -> bool {
self.matcher_type == other.matcher_type
&& self.mime_type == other.mime_type
&& self.extension == other.extension
}
}
/// Infer allows to use a custom set of `Matcher`s for infering a MIME type.
///
/// Most operations can be done by using the _top level functions_, but when custom matchers
/// are needed every call has to go through the `Infer` struct to be able
/// to see the custom matchers.
pub struct Infer {
#[cfg(feature = "alloc")]
mmap: Vec,
}
impl Infer {
/// Initialize a new instance of the infer struct.
pub const fn new() -> Infer {
#[cfg(feature = "alloc")]
return Infer { mmap: Vec::new() };
#[cfg(not(feature = "alloc"))]
return Infer {};
}
fn iter_matchers(&self) -> impl Iterator- {
let mmap = MATCHER_MAP.iter();
#[cfg(feature = "alloc")]
return self.mmap.iter().chain(mmap);
#[cfg(not(feature = "alloc"))]
return mmap;
}
/// Returns the file type of the buffer.
///
/// # Examples
///
/// ```rust
/// let info = infer::Infer::new();
/// let buf = [0xFF, 0xD8, 0xFF, 0xAA];
/// let kind = info.get(&buf).expect("file type is known");
///
/// assert_eq!(kind.mime_type(), "image/jpeg");
/// assert_eq!(kind.extension(), "jpg");
/// ```
pub fn get(&self, buf: &[u8]) -> Option {
self.iter_matchers().find(|kind| kind.matches(buf)).copied()
}
/// Returns the file type of the file given a path.
///
/// # Examples
///
/// See [`get_from_path`](./fn.get_from_path.html).
#[cfg(feature = "std")]
pub fn get_from_path>(&self, path: P) -> io::Result