Unified · Split
| @@ -50,7 +50,13 @@ pub mod reference { · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | pub mod decode { | 51 | pub mod decode { |
| 52 | use crate::loose::{reference::State, Reference, Store}; | 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 | use std::path::PathBuf; | 60 | use std::path::PathBuf; |
| 55 | 61 | ||
| 56 | impl<'a> Reference<'a> { | 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> { | 76 | fn is_hex_digit_lc(b: u8) -> bool { |
| 71 | todo!("parse loose ref bytes into reference") | 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 | } |