
Security News
New Website “Is It Really FOSS?” Tracks Transparency in Open Source Distribution Models
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
This project has been renamed to a1
- Please switch to that crate which is available
on crates.io and
github
A library for parsing to and from A1 spreadsheet notation. A1 notation uses letters A-Z for
columns and a one-based number for the row. So for example at position (0, 0)
of a spreadsheet
(the top left corner) is "A1". (1, 1)
is "B2", (1, 0)
is "B1", etc.
For serde or rkyv support, you can enable
it with the respective features (either specify features = ["serde"]
or features = ["rkyv"]
in
your Cargo.toml
).
A1
sThe most common need is to parse a string:
let a1 = A1::from_str("A1").unwrap();
// it parses it into an instance:
assert_eq!(a1,
A1 {
sheet_name: None,
reference: RangeOrCell::Cell(Address {
column: Column { absolute: false, x: 0 },
row: Row { absolute: false, y: 0 },
}),
});
// and can display it back:
assert_eq!(&a1.to_string(), "A1");
// you can also just call `a1_notation::new`:
let from_col_a_to_d = a1_notation::new("Foo!A:D").unwrap();
assert_eq!(from_col_a_to_d,
A1 {
sheet_name: Some("Foo".to_string()),
reference: RangeOrCell::ColumnRange {
from: Column { absolute: false, x: 0 },
to: Column { absolute: false, x: 3 },
},
});
assert_eq!(&from_col_a_to_d.to_string(), "Foo!A:D");
If you have zero-based coordinates and want to represent them as A1, there are several fn
s
for instantiating:
// to create a reference to a specific cell:
assert_eq!(&a1_notation::cell(2, 2).to_string(), "C3");
// a reference to an entire column
assert_eq!(&a1_notation::column(5).to_string(), "F:F");
// or an entire row
assert_eq!(&a1_notation::row(5).to_string(), "6:6");
// and finally a range between two cells:
assert_eq!(&a1_notation::range((0, 0), (4, 4)).to_string(), "A1:E5");
Given all the various combinations or cells, ranges, row ranges, column ranges and non-contiguous ranges you can calculate if one reference contains another.
// a column contains any cell in that column:
let col_a = a1_notation::new("A:A").unwrap();
let a1 = a1_notation::new("A1").unwrap();
assert!(col_a.contains(&a1));
// likewise, a row range contains anything between it:
let top_5_rows = a1_notation::new("1:5").unwrap();
let b2 = a1_notation::new("B2").unwrap();
assert!(top_5_rows.contains(&b2));
// and a range between two points works as you'd expect (it forms a rectangle)
let c3_to_j20 = a1_notation::new("C3:J20").unwrap();
let d5 = a1_notation::new("D5").unwrap();
assert!(c3_to_j20.contains(&d5));
As much as possible it implements Into
/From
and AsRef
to convert between the various
structs. Generally you can go from more specific to less specific but not the other way
around. You typically should work with A1
structs but you can also use these traits to work
with these lower level ones and cast them upwards.
// an address can act as a column or row using AsRef:
let a1 = Address::new(0, 0);
assert_eq!(&Column::new(0), a1.as_ref());
assert_eq!(&Row::new(0), a1.as_ref());
// addresses, columns and rows can `into()` "upwards" to an A1 or RangeOrCell
let col_b = Column::new(1);
assert_eq!(
RangeOrCell::ColumnRange {
from: Column::new(1),
to: Column::new(1),
},
col_b.into());
assert_eq!(
A1 {
sheet_name: None,
reference: RangeOrCell::ColumnRange {
from: Column::new(1),
to: Column::new(1),
},
},
col_b.into());
You can move references (and ranges) around:
// A1 -> D1 -> D3 -> C3
assert_eq!(
&a1_notation::cell(0, 0)
.shift_right(3)
.shift_down(2)
.shift_left(1)
.to_string(),
"C3");
You can iterate through the various types of ranges.
// a cell just emits itself (once)
assert_eq!(
a1_notation::cell(0, 0)
.iter().map(|r| r.to_string()).collect::<Vec<_>>(),
vec!["A1"]);
// a column range iterates column-wise
assert_eq!(
a1_notation::new("D:G").unwrap()
.iter().map(|r| r.to_string()).collect::<Vec<_>>(),
vec!["D:D", "E:E", "F:F", "G:G"]);
// and a row range goes row-wise
assert_eq!(
a1_notation::new("3:6").unwrap()
.iter().map(|r| r.to_string()).collect::<Vec<_>>(),
vec!["3:3", "4:4", "5:5", "6:6"]);
// a grid-based range goes row-by-row
assert_eq!(
a1_notation::new("A1:C3").unwrap()
.iter().map(|r| r.to_string()).collect::<Vec<_>>(),
vec![
"A1", "B1", "C1",
"A2", "B2", "C2",
"A3", "B3", "C3",
]);
Here is a table illustrating A1 references:
Reference | Meaning |
---|---|
"A1" | Cell A1 |
"A1:B5" | Cells A1 through B5 |
"C5:D9,G9:H16" | A multiple-area selection |
"A:A" | Column A |
"1:1" | Row 1 |
"A:C" | Columns A through C |
"1:5" | Rows 1 through 5 |
"1:1,3:3,8:8" | Rows 1, 3, and 8 |
"A:A,C:C,F:F" | Columns A, C, and F |
For more info take a look at the package on crates.io and it's Rust docs.
FAQs
Unknown package
We found that a1-notation demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.
Security News
Astral unveils pyx, a Python-native package registry in beta, designed to speed installs, enhance security, and integrate deeply with uv.
Security News
The Latio podcast explores how static and runtime reachability help teams prioritize exploitable vulnerabilities and streamline AppSec workflows.