Unified · Split
| @@ -50,7 +50,13 @@ pub mod reference { · 49 unmodified lines | ||
| 50 | 50 | |
| 51 | 51 | pub mod decode { |
| 52 | 52 | use crate::loose::{reference::State, Reference, Store}; |
| 53 | − use nom::IResult; | |
| 53 | + use git_hash::ObjectId; | |
| 54 | + use nom::branch::alt; | |
| 55 | + use nom::{ | |
| 56 | + bytes::complete::{tag, take_while_m_n}, | |
| 57 | + sequence::terminated, | |
| 58 | + IResult, | |
| 59 | + }; | |
| 54 | 60 | use std::path::PathBuf; |
| 55 | 61 | |
| 56 | 62 | impl<'a> Reference<'a> { |
| @@ -67,8 +73,21 @@ pub mod reference { · 10 unmodified lines | ||
| 67 | 73 | } |
| 68 | 74 | } |
| 69 | 75 | |
| 70 | − fn parse(_bytes: &[u8]) -> IResult<&[u8], State> { | |
| 71 | − todo!("parse loose ref bytes into reference") | |
| 76 | + fn is_hex_digit_lc(b: u8) -> bool { | |
| 77 | + matches!(b, b'0'..=b'9' | b'a'..=b'f') | |
| 78 | + } | |
| 79 | + | |
| 80 | + fn hex_sha1(i: &[u8]) -> IResult<&[u8], &[u8]> { | |
| 81 | + take_while_m_n(40usize, 40, is_hex_digit_lc)(i) | |
| 82 | + } | |
| 83 | + | |
| 84 | + fn newline(i: &[u8]) -> IResult<&[u8], &[u8]> { | |
| 85 | + alt((tag(b"\r\n"), tag(b"\n")))(i) | |
| 86 | + } | |
| 87 | + | |
| 88 | + fn parse(bytes: &[u8]) -> IResult<&[u8], State> { | |
| 89 | + let (i, hex) = terminated(hex_sha1, newline)(bytes)?; | |
| 90 | + Ok((i, State::Id(ObjectId::from_hex(hex).expect("prior validation")))) | |
| 72 | 91 | } |
| 73 | 92 | } |
| 74 | 93 | } |