Skip to main content

vasp_poscar/
lib.rs

1// Copyright 2018 Michael Lamparski
2// Part of the vasp-poscar crate.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10#![doc(html_root_url = "https://docs.rs/vasp-poscar/0.3.2")]
11
12//! Library for reading and writing [VASP POSCAR] files.
13//!
14//! See the [`Poscar`] type for more details.
15//!
16//! ```rust
17//! # fn main() -> Result<(), failure::Error> {Ok({
18//! use vasp_poscar::{Poscar, ScaleLine};
19//!
20//! const EXAMPLE: &'static str = "\
21//! cubic diamond
22//!   3.7
23//!     0.5 0.5 0.0
24//!     0.0 0.5 0.5
25//!     0.5 0.0 0.5
26//!    C
27//!    2
28//! Direct
29//!   0.0 0.0 0.0
30//!   0.25 0.25 0.25
31//! ";
32//!
33//! // read from a BufRead instance, such as &[u8] or BufReader<File>
34//! let poscar = Poscar::from_reader(EXAMPLE.as_bytes())?;
35//!
36//! // get a RawPoscar object with public fields you can freely match on and manipulate
37//! let mut poscar = poscar.into_raw();
38//! assert_eq!(poscar.scale, ScaleLine::Factor(3.7));
39//!
40//! poscar.comment = "[Subject Name Here] was here".into();
41//! poscar.scale = ScaleLine::Volume(10.0);
42//!
43//! // Turn the RawPoscar back into a Poscar
44//! let poscar = poscar.validate()?;
45//!
46//! // Poscar implements Display
47//! assert_eq!(
48//!     format!("{}", poscar),
49//!     "\
50//! [Subject Name Here] was here
51//!   -10.0
52//!     0.5 0.5 0.0
53//!     0.0 0.5 0.5
54//!     0.5 0.0 0.5
55//!    C
56//!    2
57//! Direct
58//!   0.0 0.0 0.0
59//!   0.25 0.25 0.25
60//! ");
61//! # })}
62//! ```
63//!
64//! [VASP POSCAR]: http://cms.mpi.univie.ac.at/vasp/guide/node59.html
65//! [`Poscar`]: struct.Poscar.html
66
67#[macro_use]
68pub extern crate failure;
69
70#[macro_use]
71mod util;
72mod parse;
73mod types;
74mod write;
75mod math;
76pub mod builder;
77
78pub use crate::types::{Coords, ScaleLine, RawPoscar, Poscar};
79pub use crate::types::ValidationError;
80pub use crate::builder::{Builder, Zeroed};
81
82/// Types convertable into `Vec<[X; 3]>`.
83///
84/// Appears in generic bounds for some of the crate's public API methods
85/// (such as [`Builder`]).
86///
87/// # Example implementors:
88/// <!-- @@To3 -->
89///
90/// * `Vec<[X; 3]>`
91/// * `&[[X; 3]]` (where `X: Clone`)
92/// * Any iterable of `(X, X, X)`
93///
94/// [`Builder`]: builder/struct.Builder.html
95pub trait ToN3<X>: IntoIterator {
96    #[doc(hidden)]
97    fn _to_enn_3(self) -> Vec<[X; 3]>;
98}
99
100impl<X, V, Vs> ToN3<X> for Vs
101where
102    Vs: IntoIterator<Item=V>,
103    V: To3<X>,
104{
105    fn _to_enn_3(self) -> Vec<[X; 3]>
106    { self.into_iter().map(To3::_to_array_3).collect() }
107}
108
109/// Types convertible into `[X; 3]`.
110///
111/// Appears in generic bounds for some of the crate's public API methods
112/// (such as [`Builder`]).
113///
114/// [`Builder`]: builder/struct.Builder.html
115pub trait To3<X> {
116    #[doc(hidden)]
117    fn _to_array_3(self) -> [X; 3];
118}
119
120// NOTE: When adding new impls, search for the string @@To3@@
121//       and update those docs accordingly.
122
123impl<X> To3<X> for [X; 3] {
124    fn _to_array_3(self) -> [X; 3] { self }
125}
126
127impl<'a, X> To3<X> for &'a [X; 3] where X: Clone {
128    fn _to_array_3(self) -> [X; 3] { self.clone() }
129}
130
131impl<X> To3<X> for (X, X, X) {
132    fn _to_array_3(self) -> [X; 3] { [self.0, self.1, self.2] }
133}